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"
35 #include "librpc/gen_ndr/ndr_dssetup.h"
38 this type allows us to distinguish handle types
44 LSA_HANDLE_TRUSTED_DOMAIN
48 state associated with a lsa_OpenPolicy() operation
50 struct lsa_policy_state {
51 struct dcesrv_handle *handle;
52 struct ldb_context *sam_ldb;
53 struct sidmap_context *sidmap;
55 const struct ldb_dn *domain_dn;
56 const struct ldb_dn *builtin_dn;
57 const struct ldb_dn *system_dn;
58 const char *domain_name;
59 const char *domain_dns;
60 struct dom_sid *domain_sid;
61 struct GUID domain_guid;
62 struct dom_sid *builtin_sid;
68 state associated with a lsa_OpenAccount() operation
70 struct lsa_account_state {
71 struct lsa_policy_state *policy;
73 struct dom_sid *account_sid;
78 state associated with a lsa_OpenSecret() operation
80 struct lsa_secret_state {
81 struct lsa_policy_state *policy;
83 struct ldb_dn *secret_dn;
84 struct ldb_context *sam_ldb;
89 state associated with a lsa_OpenTrustedDomain() operation
91 struct lsa_trusted_domain_state {
92 struct lsa_policy_state *policy;
94 const struct ldb_dn *trusted_domain_dn;
97 static NTSTATUS lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
99 struct lsa_EnumAccountRights *r);
101 static NTSTATUS lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
103 struct lsa_policy_state *state,
106 const struct lsa_RightSet *rights);
111 static NTSTATUS lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
114 struct dcesrv_handle *h;
116 *r->out.handle = *r->in.handle;
118 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
122 ZERO_STRUCTP(r->out.handle);
131 static NTSTATUS lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
132 struct lsa_Delete *r)
134 struct dcesrv_handle *h;
137 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
138 if (h->wire_handle.handle_type == LSA_HANDLE_SECRET) {
139 struct lsa_secret_state *secret_state = h->data;
140 ret = samdb_delete(secret_state->sam_ldb, mem_ctx, secret_state->secret_dn);
143 return NT_STATUS_INVALID_HANDLE;
147 } else if (h->wire_handle.handle_type == LSA_HANDLE_TRUSTED_DOMAIN) {
148 struct lsa_trusted_domain_state *trusted_domain_state = h->data;
149 ret = samdb_delete(trusted_domain_state->policy->sam_ldb, mem_ctx,
150 trusted_domain_state->trusted_domain_dn);
153 return NT_STATUS_INVALID_HANDLE;
157 } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
158 struct lsa_RightSet *rights;
159 struct lsa_account_state *astate;
160 struct lsa_EnumAccountRights r2;
163 rights = talloc(mem_ctx, struct lsa_RightSet);
165 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
169 r2.in.handle = &astate->policy->handle->wire_handle;
170 r2.in.sid = astate->account_sid;
171 r2.out.rights = rights;
173 status = lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
174 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
178 if (!NT_STATUS_IS_OK(status)) {
182 status = lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
183 LDB_FLAG_MOD_DELETE, astate->account_sid,
185 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
189 if (!NT_STATUS_IS_OK(status)) {
194 return NT_STATUS_INVALID_HANDLE;
201 static NTSTATUS lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
202 struct lsa_EnumPrivs *r)
204 struct dcesrv_handle *h;
205 struct lsa_policy_state *state;
207 const char *privname;
209 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
213 i = *r->in.resume_handle;
216 while ((privname = sec_privilege_name(i)) &&
217 r->out.privs->count < r->in.max_count) {
218 struct lsa_PrivEntry *e;
220 r->out.privs->privs = talloc_realloc(r->out.privs,
222 struct lsa_PrivEntry,
223 r->out.privs->count+1);
224 if (r->out.privs->privs == NULL) {
225 return NT_STATUS_NO_MEMORY;
227 e = &r->out.privs->privs[r->out.privs->count];
230 e->name.string = privname;
231 r->out.privs->count++;
235 *r->out.resume_handle = i;
244 static NTSTATUS lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
245 struct lsa_QuerySecurity *r)
247 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
254 static NTSTATUS lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
255 struct lsa_SetSecObj *r)
257 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
264 static NTSTATUS lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
265 struct lsa_ChangePassword *r)
267 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
270 static NTSTATUS lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
271 struct lsa_policy_state **_state)
273 struct lsa_policy_state *state;
274 const struct ldb_dn *partitions_basedn;
275 struct ldb_result *dom_res;
276 const char *dom_attrs[] = {
282 struct ldb_result *ref_res;
283 const char *ref_attrs[] = {
291 state = talloc(mem_ctx, struct lsa_policy_state);
293 return NT_STATUS_NO_MEMORY;
296 /* make sure the sam database is accessible */
297 state->sam_ldb = samdb_connect(state, dce_call->conn->auth_state.session_info);
298 if (state->sam_ldb == NULL) {
299 return NT_STATUS_INVALID_SYSTEM_SERVICE;
302 partitions_basedn = samdb_partitions_dn(state->sam_ldb, mem_ctx);
304 state->sidmap = sidmap_open(state);
305 if (state->sidmap == NULL) {
306 return NT_STATUS_INVALID_SYSTEM_SERVICE;
309 /* work out the domain_dn - useful for so many calls its worth
311 state->domain_dn = samdb_base_dn(state->sam_ldb);
312 if (!state->domain_dn) {
313 return NT_STATUS_NO_MEMORY;
316 ret = ldb_search(state->sam_ldb, state->domain_dn, LDB_SCOPE_BASE, NULL, dom_attrs, &dom_res);
318 if (ret != LDB_SUCCESS) {
319 return NT_STATUS_INVALID_SYSTEM_SERVICE;
321 talloc_steal(state, dom_res);
322 if (dom_res->count != 1) {
323 return NT_STATUS_NO_SUCH_DOMAIN;
326 state->domain_sid = samdb_result_dom_sid(state, dom_res->msgs[0], "objectSid");
327 if (!state->domain_sid) {
328 return NT_STATUS_NO_SUCH_DOMAIN;
331 state->domain_guid = samdb_result_guid(dom_res->msgs[0], "objectGUID");
332 if (!state->domain_sid) {
333 return NT_STATUS_NO_SUCH_DOMAIN;
336 state->mixed_domain = ldb_msg_find_attr_as_uint(dom_res->msgs[0], "nTMixedDomain", 0);
338 talloc_free(dom_res);
340 ref_filter = talloc_asprintf(state, "(&(objectclass=crossRef)(ncName=%s))",
341 ldb_dn_linearize(mem_ctx, state->domain_dn));
343 return NT_STATUS_NO_MEMORY;
346 ret = ldb_search(state->sam_ldb, partitions_basedn, LDB_SCOPE_SUBTREE, ref_filter, ref_attrs, &ref_res);
347 talloc_steal(state, ref_res);
348 talloc_free(ref_filter);
350 if (ret != LDB_SUCCESS) {
351 return NT_STATUS_INVALID_SYSTEM_SERVICE;
353 if (ref_res->count != 1) {
354 return NT_STATUS_NO_SUCH_DOMAIN;
357 state->domain_name = ldb_msg_find_attr_as_string(ref_res->msgs[0], "nETBIOSName", NULL);
358 if (!state->domain_name) {
359 return NT_STATUS_NO_SUCH_DOMAIN;
361 talloc_steal(state, state->domain_name);
363 state->domain_dns = ldb_msg_find_attr_as_string(ref_res->msgs[0], "dnsRoot", NULL);
364 if (!state->domain_dns) {
365 return NT_STATUS_NO_SUCH_DOMAIN;
367 talloc_steal(state, state->domain_dns);
369 talloc_free(ref_res);
371 /* work out the builtin_dn - useful for so many calls its worth
373 state->builtin_dn = samdb_search_dn(state->sam_ldb, state, state->domain_dn, "(objectClass=builtinDomain)");
374 if (!state->builtin_dn) {
375 return NT_STATUS_NO_SUCH_DOMAIN;
378 /* work out the system_dn - useful for so many calls its worth
380 state->system_dn = samdb_search_dn(state->sam_ldb, state,
381 state->domain_dn, "(&(objectClass=container)(cn=System))");
382 if (!state->system_dn) {
383 return NT_STATUS_NO_SUCH_DOMAIN;
386 state->builtin_sid = dom_sid_parse_talloc(state, SID_BUILTIN);
387 if (!state->builtin_sid) {
388 return NT_STATUS_NO_SUCH_DOMAIN;
397 dssetup_DsRoleGetPrimaryDomainInformation
399 static WERROR dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state *dce_call,
401 struct dssetup_DsRoleGetPrimaryDomainInformation *r)
403 union dssetup_DsRoleInfo *info;
405 info = talloc(mem_ctx, union dssetup_DsRoleInfo);
406 W_ERROR_HAVE_NO_MEMORY(info);
408 switch (r->in.level) {
409 case DS_ROLE_BASIC_INFORMATION:
411 enum dssetup_DsRole role = DS_ROLE_STANDALONE_SERVER;
413 const char *domain = NULL;
414 const char *dns_domain = NULL;
415 const char *forest = NULL;
416 struct GUID domain_guid;
417 struct lsa_policy_state *state;
419 NTSTATUS status = lsa_get_policy_state(dce_call, mem_ctx, &state);
420 if (!NT_STATUS_IS_OK(status)) {
421 return ntstatus_to_werror(status);
424 ZERO_STRUCT(domain_guid);
426 switch (lp_server_role()) {
427 case ROLE_STANDALONE:
428 role = DS_ROLE_STANDALONE_SERVER;
430 case ROLE_DOMAIN_MEMBER:
431 role = DS_ROLE_MEMBER_SERVER;
433 case ROLE_DOMAIN_BDC:
434 role = DS_ROLE_BACKUP_DC;
436 case ROLE_DOMAIN_PDC:
437 role = DS_ROLE_PRIMARY_DC;
441 switch (lp_server_role()) {
442 case ROLE_STANDALONE:
443 domain = talloc_strdup(mem_ctx, lp_workgroup());
444 W_ERROR_HAVE_NO_MEMORY(domain);
446 case ROLE_DOMAIN_MEMBER:
447 domain = talloc_strdup(mem_ctx, lp_workgroup());
448 W_ERROR_HAVE_NO_MEMORY(domain);
449 /* TODO: what is with dns_domain and forest and guid? */
451 case ROLE_DOMAIN_BDC:
452 case ROLE_DOMAIN_PDC:
453 flags = DS_ROLE_PRIMARY_DS_RUNNING;
455 if (state->mixed_domain == 1) {
456 flags |= DS_ROLE_PRIMARY_DS_MIXED_MODE;
459 domain = state->domain_name;
460 dns_domain = state->domain_dns;
461 forest = state->domain_dns;
463 domain_guid = state->domain_guid;
464 flags |= DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT;
468 info->basic.role = role;
469 info->basic.flags = flags;
470 info->basic.domain = domain;
471 info->basic.dns_domain = dns_domain;
472 info->basic.forest = forest;
473 info->basic.domain_guid = domain_guid;
478 case DS_ROLE_UPGRADE_STATUS:
480 info->upgrade.upgrading = DS_ROLE_NOT_UPGRADING;
481 info->upgrade.previous_role = DS_ROLE_PREVIOUS_UNKNOWN;
486 case DS_ROLE_OP_STATUS:
488 info->opstatus.status = DS_ROLE_OP_IDLE;
494 return WERR_INVALID_PARAM;
497 return WERR_INVALID_PARAM;
503 static NTSTATUS lsa_OpenPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
504 struct lsa_OpenPolicy2 *r)
507 struct lsa_policy_state *state;
508 struct dcesrv_handle *handle;
510 ZERO_STRUCTP(r->out.handle);
512 status = lsa_get_policy_state(dce_call, mem_ctx, &state);
513 if (!NT_STATUS_IS_OK(status)) {
517 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_POLICY);
519 return NT_STATUS_NO_MEMORY;
522 handle->data = talloc_steal(handle, state);
524 state->access_mask = r->in.access_mask;
525 state->handle = handle;
526 *r->out.handle = handle->wire_handle;
528 /* note that we have completely ignored the attr element of
529 the OpenPolicy. As far as I can tell, this is what w2k3
537 a wrapper around lsa_OpenPolicy2
539 static NTSTATUS lsa_OpenPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
540 struct lsa_OpenPolicy *r)
542 struct lsa_OpenPolicy2 r2;
544 r2.in.system_name = NULL;
545 r2.in.attr = r->in.attr;
546 r2.in.access_mask = r->in.access_mask;
547 r2.out.handle = r->out.handle;
549 return lsa_OpenPolicy2(dce_call, mem_ctx, &r2);
556 fill in the AccountDomain info
558 static NTSTATUS lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
559 struct lsa_DomainInfo *info)
561 info->name.string = state->domain_name;
562 info->sid = state->domain_sid;
568 fill in the DNS domain info
570 static NTSTATUS lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
571 struct lsa_DnsDomainInfo *info)
573 info->name.string = state->domain_name;
574 info->sid = state->domain_sid;
575 info->dns_domain.string = state->domain_dns;
576 info->dns_forest.string = state->domain_dns;
577 info->domain_guid = state->domain_guid;
585 static NTSTATUS lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
586 struct lsa_QueryInfoPolicy2 *r)
588 struct lsa_policy_state *state;
589 struct dcesrv_handle *h;
593 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
597 r->out.info = talloc(mem_ctx, union lsa_PolicyInformation);
599 return NT_STATUS_NO_MEMORY;
602 ZERO_STRUCTP(r->out.info);
604 switch (r->in.level) {
605 case LSA_POLICY_INFO_DOMAIN:
606 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
607 return lsa_info_AccountDomain(state, mem_ctx, &r->out.info->account_domain);
609 case LSA_POLICY_INFO_DNS:
610 return lsa_info_DNS(state, mem_ctx, &r->out.info->dns);
613 return NT_STATUS_INVALID_INFO_CLASS;
619 static NTSTATUS lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
620 struct lsa_QueryInfoPolicy *r)
622 struct lsa_QueryInfoPolicy2 r2;
625 r2.in.handle = r->in.handle;
626 r2.in.level = r->in.level;
628 status = lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
630 r->out.info = r2.out.info;
638 static NTSTATUS lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
639 struct lsa_SetInfoPolicy *r)
641 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
648 static NTSTATUS lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
649 struct lsa_ClearAuditLog *r)
651 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
658 static NTSTATUS lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
659 struct lsa_CreateAccount *r)
661 struct lsa_account_state *astate;
663 struct lsa_policy_state *state;
664 struct dcesrv_handle *h, *ah;
666 ZERO_STRUCTP(r->out.acct_handle);
668 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
672 astate = talloc(dce_call->conn, struct lsa_account_state);
673 if (astate == NULL) {
674 return NT_STATUS_NO_MEMORY;
677 astate->account_sid = dom_sid_dup(astate, r->in.sid);
678 if (astate->account_sid == NULL) {
680 return NT_STATUS_NO_MEMORY;
683 astate->policy = talloc_reference(astate, state);
684 astate->access_mask = r->in.access_mask;
686 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
689 return NT_STATUS_NO_MEMORY;
692 ah->data = talloc_steal(ah, astate);
694 *r->out.acct_handle = ah->wire_handle;
703 static NTSTATUS lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
704 struct lsa_EnumAccounts *r)
706 struct dcesrv_handle *h;
707 struct lsa_policy_state *state;
709 struct ldb_message **res;
710 const char * const attrs[] = { "objectSid", NULL};
713 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
717 /* NOTE: This call must only return accounts that have at least
720 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
721 "(&(objectSid=*)(privilege=*))");
723 return NT_STATUS_NO_SUCH_USER;
726 if (*r->in.resume_handle >= ret) {
727 return NT_STATUS_NO_MORE_ENTRIES;
730 count = ret - *r->in.resume_handle;
731 if (count > r->in.num_entries) {
732 count = r->in.num_entries;
736 return NT_STATUS_NO_MORE_ENTRIES;
739 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, count);
740 if (r->out.sids->sids == NULL) {
741 return NT_STATUS_NO_MEMORY;
744 for (i=0;i<count;i++) {
745 r->out.sids->sids[i].sid =
746 samdb_result_dom_sid(r->out.sids->sids,
747 res[i + *r->in.resume_handle],
749 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
752 r->out.sids->num_sids = count;
753 *r->out.resume_handle = count + *r->in.resume_handle;
761 lsa_CreateTrustedDomainEx2
763 static NTSTATUS lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
765 struct lsa_CreateTrustedDomainEx2 *r)
767 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
771 lsa_CreateTrustedDomainEx
773 static NTSTATUS lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
775 struct lsa_CreateTrustedDomainEx *r)
777 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
781 lsa_CreateTrustedDomain
783 static NTSTATUS lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
784 struct lsa_CreateTrustedDomain *r)
786 struct dcesrv_handle *policy_handle;
787 struct lsa_policy_state *policy_state;
788 struct lsa_trusted_domain_state *trusted_domain_state;
789 struct dcesrv_handle *handle;
790 struct ldb_message **msgs, *msg;
791 const char *attrs[] = {
797 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
798 ZERO_STRUCTP(r->out.trustdom_handle);
800 policy_state = policy_handle->data;
802 if (!r->in.info->name.string) {
803 return NT_STATUS_INVALID_PARAMETER;
805 name = r->in.info->name.string;
807 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
808 if (!trusted_domain_state) {
809 return NT_STATUS_NO_MEMORY;
811 trusted_domain_state->policy = policy_state;
813 msg = ldb_msg_new(mem_ctx);
815 return NT_STATUS_NO_MEMORY;
818 /* search for the trusted_domain record */
819 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
820 mem_ctx, policy_state->system_dn, &msgs, attrs,
821 "(&(cn=%s)(objectclass=trustedDomain))",
822 ldb_binary_encode_string(mem_ctx, r->in.info->name.string));
824 return NT_STATUS_OBJECT_NAME_COLLISION;
827 if (ret < 0 || ret > 1) {
828 DEBUG(0,("Found %d records matching DN %s\n", ret,
829 ldb_dn_linearize(mem_ctx, policy_state->system_dn)));
830 return NT_STATUS_INTERNAL_DB_CORRUPTION;
833 msg->dn = ldb_dn_build_child(mem_ctx, "cn",
834 r->in.info->name.string,
835 policy_state->system_dn);
837 return NT_STATUS_NO_MEMORY;
840 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "cn", name);
841 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "flatname", name);
843 if (r->in.info->sid) {
844 const char *sid_string = dom_sid_string(mem_ctx, r->in.info->sid);
846 return NT_STATUS_NO_MEMORY;
849 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "securityIdentifier", sid_string);
852 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "objectClass", "trustedDomain");
854 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
856 /* create the trusted_domain */
857 ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg);
858 if (ret != LDB_SUCCESS) {
859 DEBUG(0,("Failed to create trusted_domain record %s: %s\n",
860 ldb_dn_linearize(mem_ctx, msg->dn), ldb_errstring(trusted_domain_state->policy->sam_ldb)));
861 return NT_STATUS_INTERNAL_DB_CORRUPTION;
864 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
866 return NT_STATUS_NO_MEMORY;
869 handle->data = talloc_steal(handle, trusted_domain_state);
871 trusted_domain_state->access_mask = r->in.access_mask;
872 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
874 *r->out.trustdom_handle = handle->wire_handle;
880 lsa_OpenTrustedDomain
882 static NTSTATUS lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
883 struct lsa_OpenTrustedDomain *r)
885 struct dcesrv_handle *policy_handle;
887 struct lsa_policy_state *policy_state;
888 struct lsa_trusted_domain_state *trusted_domain_state;
889 struct dcesrv_handle *handle;
890 struct ldb_message **msgs;
891 const char *attrs[] = {
895 const char *sid_string;
898 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
899 ZERO_STRUCTP(r->out.trustdom_handle);
900 policy_state = policy_handle->data;
902 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
903 if (!trusted_domain_state) {
904 return NT_STATUS_NO_MEMORY;
906 trusted_domain_state->policy = policy_state;
908 sid_string = dom_sid_string(mem_ctx, r->in.sid);
910 return NT_STATUS_NO_MEMORY;
913 /* search for the trusted_domain record */
914 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
915 mem_ctx, policy_state->system_dn, &msgs, attrs,
916 "(&(securityIdentifier=%s)(objectclass=trustedDomain))",
919 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
923 DEBUG(0,("Found %d records matching DN %s\n", ret,
924 ldb_dn_linearize(mem_ctx, policy_state->system_dn)));
925 return NT_STATUS_INTERNAL_DB_CORRUPTION;
928 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
930 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
932 return NT_STATUS_NO_MEMORY;
935 handle->data = talloc_steal(handle, trusted_domain_state);
937 trusted_domain_state->access_mask = r->in.access_mask;
938 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
940 *r->out.trustdom_handle = handle->wire_handle;
947 lsa_OpenTrustedDomainByName
949 static NTSTATUS lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
951 struct lsa_OpenTrustedDomainByName *r)
953 struct dcesrv_handle *policy_handle;
955 struct lsa_policy_state *policy_state;
956 struct lsa_trusted_domain_state *trusted_domain_state;
957 struct dcesrv_handle *handle;
958 struct ldb_message **msgs;
959 const char *attrs[] = {
965 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
966 ZERO_STRUCTP(r->out.trustdom_handle);
967 policy_state = policy_handle->data;
969 if (!r->in.name.string) {
970 return NT_STATUS_INVALID_PARAMETER;
973 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
974 if (!trusted_domain_state) {
975 return NT_STATUS_NO_MEMORY;
977 trusted_domain_state->policy = policy_state;
979 /* search for the trusted_domain record */
980 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
981 mem_ctx, policy_state->system_dn, &msgs, attrs,
982 "(&(flatname=%s)(objectclass=trustedDomain))",
983 ldb_binary_encode_string(mem_ctx, r->in.name.string));
985 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
989 DEBUG(0,("Found %d records matching DN %s\n", ret,
990 ldb_dn_linearize(mem_ctx, policy_state->system_dn)));
991 return NT_STATUS_INTERNAL_DB_CORRUPTION;
994 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
996 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
998 return NT_STATUS_NO_MEMORY;
1001 handle->data = talloc_steal(handle, trusted_domain_state);
1003 trusted_domain_state->access_mask = r->in.access_mask;
1004 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1006 *r->out.trustdom_handle = handle->wire_handle;
1008 return NT_STATUS_OK;
1014 lsa_SetTrustedDomainInfo
1016 static NTSTATUS lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1017 struct lsa_SetTrustedDomainInfo *r)
1019 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1025 lsa_SetInfomrationTrustedDomain
1027 static NTSTATUS lsa_SetInformationTrustedDomain(struct dcesrv_call_state *dce_call,
1028 TALLOC_CTX *mem_ctx,
1029 struct lsa_SetInformationTrustedDomain *r)
1031 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1036 lsa_DeleteTrustedDomain
1038 static NTSTATUS lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1039 struct lsa_DeleteTrustedDomain *r)
1042 struct lsa_OpenTrustedDomain open;
1043 struct lsa_Delete delete;
1044 struct dcesrv_handle *h;
1046 open.in.handle = r->in.handle;
1047 open.in.sid = r->in.dom_sid;
1048 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1049 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1050 if (!open.out.trustdom_handle) {
1051 return NT_STATUS_NO_MEMORY;
1053 status = lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
1054 if (!NT_STATUS_IS_OK(status)) {
1058 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1059 talloc_steal(mem_ctx, h);
1061 delete.in.handle = open.out.trustdom_handle;
1062 status = lsa_Delete(dce_call, mem_ctx, &delete);
1063 if (!NT_STATUS_IS_OK(status)) {
1066 return NT_STATUS_OK;
1069 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx,
1070 struct ldb_message *msg,
1071 struct lsa_TrustDomainInfoInfoEx *info_ex)
1073 info_ex->domain_name.string
1074 = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
1075 info_ex->netbios_name.string
1076 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1078 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1079 info_ex->trust_direction
1080 = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
1082 = ldb_msg_find_attr_as_int(msg, "trustType", 0);
1083 info_ex->trust_attributes
1084 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);
1085 return NT_STATUS_OK;
1089 lsa_QueryTrustedDomainInfo
1091 static NTSTATUS lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1092 struct lsa_QueryTrustedDomainInfo *r)
1094 struct dcesrv_handle *h;
1095 struct lsa_trusted_domain_state *trusted_domain_state;
1096 struct ldb_message *msg;
1098 struct ldb_message **res;
1099 const char *attrs[] = {
1102 "securityIdentifier",
1109 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
1111 trusted_domain_state = h->data;
1113 /* pull all the user attributes */
1114 ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
1115 trusted_domain_state->trusted_domain_dn, &res, attrs);
1117 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1121 r->out.info = talloc(mem_ctx, union lsa_TrustedDomainInfo);
1123 return NT_STATUS_NO_MEMORY;
1125 switch (r->in.level) {
1126 case LSA_TRUSTED_DOMAIN_INFO_NAME:
1127 r->out.info->name.netbios_name.string
1128 = samdb_result_string(msg, "flatname", NULL);
1130 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1131 r->out.info->posix_offset.posix_offset
1132 = samdb_result_uint(msg, "posixOffset", 0);
1134 #if 0 /* Win2k3 doesn't implement this */
1135 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
1136 r->out.info->info_basic.netbios_name.string
1137 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1138 r->out.info->info_basic.sid
1139 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1142 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1143 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->info_ex);
1145 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1146 ZERO_STRUCT(r->out.info->full_info);
1147 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->full_info.info_ex);
1149 case LSA_TRUSTED_DOMAIN_INFO_INFO_ALL:
1150 ZERO_STRUCT(r->out.info->info_all);
1151 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->info_all.info_ex);
1153 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS_INFO:
1154 case LSA_TRUSTED_DOMAIN_INFO_11:
1155 /* oops, we don't want to return the info after all */
1156 talloc_free(r->out.info);
1158 return NT_STATUS_INVALID_PARAMETER;
1160 /* oops, we don't want to return the info after all */
1161 talloc_free(r->out.info);
1163 return NT_STATUS_INVALID_INFO_CLASS;
1166 return NT_STATUS_OK;
1171 lsa_QueryTrustedDomainInfoBySid
1173 static NTSTATUS lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1174 struct lsa_QueryTrustedDomainInfoBySid *r)
1177 struct lsa_OpenTrustedDomain open;
1178 struct lsa_QueryTrustedDomainInfo query;
1179 struct dcesrv_handle *h;
1180 open.in.handle = r->in.handle;
1181 open.in.sid = r->in.dom_sid;
1182 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1183 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1184 if (!open.out.trustdom_handle) {
1185 return NT_STATUS_NO_MEMORY;
1187 status = lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
1188 if (!NT_STATUS_IS_OK(status)) {
1192 /* Ensure this handle goes away at the end of this call */
1193 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1194 talloc_steal(mem_ctx, h);
1196 query.in.trustdom_handle = open.out.trustdom_handle;
1197 query.in.level = r->in.level;
1198 status = lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1199 if (!NT_STATUS_IS_OK(status)) {
1203 r->out.info = query.out.info;
1204 return NT_STATUS_OK;
1208 lsa_SetTrustedDomainInfoByName
1210 static NTSTATUS lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1211 TALLOC_CTX *mem_ctx,
1212 struct lsa_SetTrustedDomainInfoByName *r)
1214 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1218 lsa_QueryTrustedDomainInfoByName
1220 static NTSTATUS lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1221 TALLOC_CTX *mem_ctx,
1222 struct lsa_QueryTrustedDomainInfoByName *r)
1225 struct lsa_OpenTrustedDomainByName open;
1226 struct lsa_QueryTrustedDomainInfo query;
1227 struct dcesrv_handle *h;
1228 open.in.handle = r->in.handle;
1229 open.in.name = r->in.trusted_domain;
1230 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1231 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1232 if (!open.out.trustdom_handle) {
1233 return NT_STATUS_NO_MEMORY;
1235 status = lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &open);
1236 if (!NT_STATUS_IS_OK(status)) {
1240 /* Ensure this handle goes away at the end of this call */
1241 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1242 talloc_steal(mem_ctx, h);
1244 query.in.trustdom_handle = open.out.trustdom_handle;
1245 query.in.level = r->in.level;
1246 status = lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1247 if (!NT_STATUS_IS_OK(status)) {
1251 r->out.info = query.out.info;
1252 return NT_STATUS_OK;
1256 lsa_CloseTrustedDomainEx
1258 static NTSTATUS lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
1259 TALLOC_CTX *mem_ctx,
1260 struct lsa_CloseTrustedDomainEx *r)
1262 /* The result of a bad hair day from an IDL programmer? Not
1263 * implmented in Win2k3. You should always just lsa_Close
1265 return NT_STATUS_NOT_IMPLEMENTED;
1270 comparison function for sorting lsa_DomainInformation array
1272 static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
1274 return strcasecmp(e1->name.string, e2->name.string);
1280 static NTSTATUS lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1281 struct lsa_EnumTrustDom *r)
1283 struct dcesrv_handle *policy_handle;
1284 struct lsa_DomainInfo *entries;
1285 struct lsa_policy_state *policy_state;
1286 struct ldb_message **domains;
1287 const char *attrs[] = {
1289 "securityIdentifier",
1296 *r->out.resume_handle = 0;
1298 r->out.domains->domains = NULL;
1299 r->out.domains->count = 0;
1301 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1303 policy_state = policy_handle->data;
1305 /* search for all users in this domain. This could possibly be cached and
1306 resumed based on resume_key */
1307 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1308 "objectclass=trustedDomain");
1310 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1312 if (count == 0 || r->in.max_size == 0) {
1313 return NT_STATUS_OK;
1316 /* convert to lsa_TrustInformation format */
1317 entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
1319 return NT_STATUS_NO_MEMORY;
1321 for (i=0;i<count;i++) {
1322 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
1323 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
1326 /* sort the results by name */
1327 qsort(entries, count, sizeof(*entries),
1328 (comparison_fn_t)compare_DomainInfo);
1330 if (*r->in.resume_handle >= count) {
1331 *r->out.resume_handle = -1;
1333 return NT_STATUS_NO_MORE_ENTRIES;
1336 /* return the rest, limit by max_size. Note that we
1337 use the w2k3 element size value of 60 */
1338 r->out.domains->count = count - *r->in.resume_handle;
1339 r->out.domains->count = MIN(r->out.domains->count,
1340 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
1342 r->out.domains->domains = entries + *r->in.resume_handle;
1343 r->out.domains->count = r->out.domains->count;
1345 if (r->out.domains->count < count - *r->in.resume_handle) {
1346 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1347 return STATUS_MORE_ENTRIES;
1350 return NT_STATUS_OK;
1354 comparison function for sorting lsa_DomainInformation array
1356 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
1358 return strcasecmp(e1->domain_name.string, e2->domain_name.string);
1362 lsa_EnumTrustedDomainsEx
1364 static NTSTATUS lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1365 struct lsa_EnumTrustedDomainsEx *r)
1367 struct dcesrv_handle *policy_handle;
1368 struct lsa_TrustDomainInfoInfoEx *entries;
1369 struct lsa_policy_state *policy_state;
1370 struct ldb_message **domains;
1371 const char *attrs[] = {
1374 "securityIdentifier",
1384 *r->out.resume_handle = 0;
1386 r->out.domains->domains = NULL;
1387 r->out.domains->count = 0;
1389 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1391 policy_state = policy_handle->data;
1393 /* search for all users in this domain. This could possibly be cached and
1394 resumed based on resume_key */
1395 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1396 "objectclass=trustedDomain");
1398 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1400 if (count == 0 || r->in.max_size == 0) {
1401 return NT_STATUS_OK;
1404 /* convert to lsa_DomainInformation format */
1405 entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
1407 return NT_STATUS_NO_MEMORY;
1409 for (i=0;i<count;i++) {
1410 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
1411 if (!NT_STATUS_IS_OK(nt_status)) {
1416 /* sort the results by name */
1417 qsort(entries, count, sizeof(*entries),
1418 (comparison_fn_t)compare_TrustDomainInfoInfoEx);
1420 if (*r->in.resume_handle >= count) {
1421 *r->out.resume_handle = -1;
1423 return NT_STATUS_NO_MORE_ENTRIES;
1426 /* return the rest, limit by max_size. Note that we
1427 use the w2k3 element size value of 60 */
1428 r->out.domains->count = count - *r->in.resume_handle;
1429 r->out.domains->count = MIN(r->out.domains->count,
1430 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
1432 r->out.domains->domains = entries + *r->in.resume_handle;
1433 r->out.domains->count = r->out.domains->count;
1435 if (r->out.domains->count < count - *r->in.resume_handle) {
1436 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1437 return STATUS_MORE_ENTRIES;
1440 return NT_STATUS_OK;
1445 return the authority name and authority sid, given a sid
1447 static NTSTATUS lsa_authority_name(struct lsa_policy_state *state,
1448 TALLOC_CTX *mem_ctx, struct dom_sid *sid,
1449 const char **authority_name,
1450 struct dom_sid **authority_sid)
1452 if (dom_sid_in_domain(state->domain_sid, sid)) {
1453 *authority_name = state->domain_name;
1454 *authority_sid = state->domain_sid;
1455 return NT_STATUS_OK;
1458 if (dom_sid_in_domain(state->builtin_sid, sid)) {
1459 *authority_name = "BUILTIN";
1460 *authority_sid = state->builtin_sid;
1461 return NT_STATUS_OK;
1464 *authority_sid = dom_sid_dup(mem_ctx, sid);
1465 if (*authority_sid == NULL) {
1466 return NT_STATUS_NO_MEMORY;
1468 (*authority_sid)->num_auths = 0;
1469 *authority_name = dom_sid_string(mem_ctx, *authority_sid);
1470 if (*authority_name == NULL) {
1471 return NT_STATUS_NO_MEMORY;
1474 return NT_STATUS_OK;
1478 add to the lsa_RefDomainList for LookupSids and LookupNames
1480 static NTSTATUS lsa_authority_list(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
1481 struct dom_sid *sid,
1482 struct lsa_RefDomainList *domains,
1483 uint32_t *sid_index)
1486 const char *authority_name;
1487 struct dom_sid *authority_sid;
1490 /* work out the authority name */
1491 status = lsa_authority_name(state, mem_ctx, sid,
1492 &authority_name, &authority_sid);
1493 if (!NT_STATUS_IS_OK(status)) {
1497 /* see if we've already done this authority name */
1498 for (i=0;i<domains->count;i++) {
1499 if (strcmp(authority_name, domains->domains[i].name.string) == 0) {
1501 return NT_STATUS_OK;
1505 domains->domains = talloc_realloc(domains,
1507 struct lsa_DomainInfo,
1509 if (domains->domains == NULL) {
1510 return NT_STATUS_NO_MEMORY;
1512 domains->domains[i].name.string = authority_name;
1513 domains->domains[i].sid = authority_sid;
1515 domains->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER * domains->count;
1518 return NT_STATUS_OK;
1522 lookup a name for 1 SID
1524 static NTSTATUS lsa_lookup_sid(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
1525 struct dom_sid *sid, const char *sid_str,
1526 const char **name, uint32_t *atype)
1529 struct ldb_message **res;
1530 const char * const attrs[] = { "sAMAccountName", "sAMAccountType", "name", NULL};
1533 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
1534 "objectSid=%s", ldap_encode_ndr_dom_sid(mem_ctx, sid));
1536 *name = ldb_msg_find_attr_as_string(res[0], "sAMAccountName", NULL);
1538 *name = ldb_msg_find_attr_as_string(res[0], "name", NULL);
1540 *name = talloc_strdup(mem_ctx, sid_str);
1541 NT_STATUS_HAVE_NO_MEMORY(*name);
1545 *atype = samdb_result_uint(res[0], "sAMAccountType", 0);
1547 return NT_STATUS_OK;
1550 status = sidmap_allocated_sid_lookup(state->sidmap, mem_ctx, sid, name, atype);
1559 static NTSTATUS lsa_LookupSids3(struct dcesrv_call_state *dce_call,
1560 TALLOC_CTX *mem_ctx,
1561 struct lsa_LookupSids3 *r)
1563 struct lsa_policy_state *state;
1565 NTSTATUS status = NT_STATUS_OK;
1567 r->out.domains = NULL;
1569 status = lsa_get_policy_state(dce_call, mem_ctx, &state);
1570 if (!NT_STATUS_IS_OK(status)) {
1574 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
1575 if (r->out.domains == NULL) {
1576 return NT_STATUS_NO_MEMORY;
1579 r->out.names = talloc_zero(mem_ctx, struct lsa_TransNameArray2);
1580 if (r->out.names == NULL) {
1581 return NT_STATUS_NO_MEMORY;
1586 r->out.names->names = talloc_array(r->out.names, struct lsa_TranslatedName2,
1587 r->in.sids->num_sids);
1588 if (r->out.names->names == NULL) {
1589 return NT_STATUS_NO_MEMORY;
1592 for (i=0;i<r->in.sids->num_sids;i++) {
1593 struct dom_sid *sid = r->in.sids->sids[i].sid;
1594 char *sid_str = dom_sid_string(mem_ctx, sid);
1596 uint32_t atype, rtype, sid_index;
1599 r->out.names->count++;
1602 r->out.names->names[i].sid_type = SID_NAME_UNKNOWN;
1603 r->out.names->names[i].name.string = sid_str;
1604 r->out.names->names[i].sid_index = 0xFFFFFFFF;
1605 r->out.names->names[i].unknown = 0;
1607 if (sid_str == NULL) {
1608 r->out.names->names[i].name.string = "(SIDERROR)";
1609 status = STATUS_SOME_UNMAPPED;
1613 /* work out the authority name */
1614 status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
1615 if (!NT_STATUS_IS_OK(status2)) {
1619 status2 = lsa_lookup_sid(state, mem_ctx, sid, sid_str,
1621 if (!NT_STATUS_IS_OK(status2)) {
1622 status = STATUS_SOME_UNMAPPED;
1626 rtype = samdb_atype_map(atype);
1627 if (rtype == SID_NAME_UNKNOWN) {
1628 status = STATUS_SOME_UNMAPPED;
1632 r->out.names->names[i].sid_type = rtype;
1633 r->out.names->names[i].name.string = name;
1634 r->out.names->names[i].sid_index = sid_index;
1635 r->out.names->names[i].unknown = 0;
1645 static NTSTATUS lsa_LookupSids2(struct dcesrv_call_state *dce_call,
1646 TALLOC_CTX *mem_ctx,
1647 struct lsa_LookupSids2 *r)
1649 struct lsa_LookupSids3 r3;
1652 r3.in.sids = r->in.sids;
1653 r3.in.names = r->in.names;
1654 r3.in.level = r->in.level;
1655 r3.in.count = r->in.count;
1656 r3.in.unknown1 = r->in.unknown1;
1657 r3.in.unknown2 = r->in.unknown2;
1658 r3.out.count = r->out.count;
1659 r3.out.names = r->out.names;
1661 status = lsa_LookupSids3(dce_call, mem_ctx, &r3);
1662 if (dce_call->fault_code != 0) {
1666 r->out.domains = r3.out.domains;
1667 r->out.names = r3.out.names;
1668 r->out.count = r3.out.count;
1677 static NTSTATUS lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1678 struct lsa_LookupSids *r)
1680 struct lsa_LookupSids3 r3;
1684 r3.in.sids = r->in.sids;
1686 r3.in.level = r->in.level;
1687 r3.in.count = r->in.count;
1690 r3.out.count = r->out.count;
1691 r3.out.names = NULL;
1693 status = lsa_LookupSids3(dce_call, mem_ctx, &r3);
1694 if (dce_call->fault_code != 0) {
1698 r->out.domains = r3.out.domains;
1699 if (!r3.out.names) {
1700 r->out.names = NULL;
1704 r->out.names = talloc(mem_ctx, struct lsa_TransNameArray);
1705 if (r->out.names == NULL) {
1706 return NT_STATUS_NO_MEMORY;
1708 r->out.names->count = r3.out.names->count;
1709 r->out.names->names = talloc_array(r->out.names, struct lsa_TranslatedName,
1710 r->out.names->count);
1711 if (r->out.names->names == NULL) {
1712 return NT_STATUS_NO_MEMORY;
1714 for (i=0;i<r->out.names->count;i++) {
1715 r->out.names->names[i].sid_type = r3.out.names->names[i].sid_type;
1716 r->out.names->names[i].name.string = r3.out.names->names[i].name.string;
1717 r->out.names->names[i].sid_index = r3.out.names->names[i].sid_index;
1727 static NTSTATUS lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1728 struct lsa_OpenAccount *r)
1730 struct dcesrv_handle *h, *ah;
1731 struct lsa_policy_state *state;
1732 struct lsa_account_state *astate;
1734 ZERO_STRUCTP(r->out.acct_handle);
1736 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1740 astate = talloc(dce_call->conn, struct lsa_account_state);
1741 if (astate == NULL) {
1742 return NT_STATUS_NO_MEMORY;
1745 astate->account_sid = dom_sid_dup(astate, r->in.sid);
1746 if (astate->account_sid == NULL) {
1747 talloc_free(astate);
1748 return NT_STATUS_NO_MEMORY;
1751 astate->policy = talloc_reference(astate, state);
1752 astate->access_mask = r->in.access_mask;
1754 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
1756 talloc_free(astate);
1757 return NT_STATUS_NO_MEMORY;
1760 ah->data = talloc_steal(ah, astate);
1762 *r->out.acct_handle = ah->wire_handle;
1764 return NT_STATUS_OK;
1769 lsa_EnumPrivsAccount
1771 static NTSTATUS lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
1772 TALLOC_CTX *mem_ctx,
1773 struct lsa_EnumPrivsAccount *r)
1775 struct dcesrv_handle *h;
1776 struct lsa_account_state *astate;
1778 struct ldb_message **res;
1779 const char * const attrs[] = { "privilege", NULL};
1780 struct ldb_message_element *el;
1783 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1787 r->out.privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
1788 r->out.privs->count = 0;
1789 r->out.privs->unknown = 0;
1790 r->out.privs->set = NULL;
1792 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
1793 if (sidstr == NULL) {
1794 return NT_STATUS_NO_MEMORY;
1797 ret = gendb_search(astate->policy->sam_ldb, mem_ctx, NULL, &res, attrs,
1798 "objectSid=%s", sidstr);
1800 return NT_STATUS_OK;
1803 el = ldb_msg_find_element(res[0], "privilege");
1804 if (el == NULL || el->num_values == 0) {
1805 return NT_STATUS_OK;
1808 r->out.privs->set = talloc_array(r->out.privs,
1809 struct lsa_LUIDAttribute, el->num_values);
1810 if (r->out.privs->set == NULL) {
1811 return NT_STATUS_NO_MEMORY;
1814 for (i=0;i<el->num_values;i++) {
1815 int id = sec_privilege_id((const char *)el->values[i].data);
1817 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1819 r->out.privs->set[i].attribute = 0;
1820 r->out.privs->set[i].luid.low = id;
1821 r->out.privs->set[i].luid.high = 0;
1824 r->out.privs->count = el->num_values;
1826 return NT_STATUS_OK;
1830 lsa_EnumAccountRights
1832 static NTSTATUS lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
1833 TALLOC_CTX *mem_ctx,
1834 struct lsa_EnumAccountRights *r)
1836 struct dcesrv_handle *h;
1837 struct lsa_policy_state *state;
1839 struct ldb_message **res;
1840 const char * const attrs[] = { "privilege", NULL};
1842 struct ldb_message_element *el;
1844 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1848 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
1849 if (sidstr == NULL) {
1850 return NT_STATUS_NO_MEMORY;
1853 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
1854 "(&(objectSid=%s)(privilege=*))", sidstr);
1856 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1859 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1862 DEBUG(3, ("searching for account rights for SID: %s failed: %s",
1863 dom_sid_string(mem_ctx, r->in.sid),
1864 ldb_errstring(state->sam_ldb)));
1865 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1868 el = ldb_msg_find_element(res[0], "privilege");
1869 if (el == NULL || el->num_values == 0) {
1870 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1873 r->out.rights->count = el->num_values;
1874 r->out.rights->names = talloc_array(r->out.rights,
1875 struct lsa_StringLarge, r->out.rights->count);
1876 if (r->out.rights->names == NULL) {
1877 return NT_STATUS_NO_MEMORY;
1880 for (i=0;i<el->num_values;i++) {
1881 r->out.rights->names[i].string = (const char *)el->values[i].data;
1884 return NT_STATUS_OK;
1890 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
1892 static NTSTATUS lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
1893 TALLOC_CTX *mem_ctx,
1894 struct lsa_policy_state *state,
1896 struct dom_sid *sid,
1897 const struct lsa_RightSet *rights)
1900 struct ldb_message *msg;
1901 struct ldb_message_element *el;
1903 struct lsa_EnumAccountRights r2;
1905 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, sid);
1906 if (sidstr == NULL) {
1907 return NT_STATUS_NO_MEMORY;
1910 msg = ldb_msg_new(mem_ctx);
1912 return NT_STATUS_NO_MEMORY;
1915 msg->dn = samdb_search_dn(state->sam_ldb, mem_ctx,
1916 NULL, "objectSid=%s", sidstr);
1917 if (msg->dn == NULL) {
1919 if (ldb_flag == LDB_FLAG_MOD_DELETE) {
1920 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1922 status = samdb_create_foreign_security_principal(state->sam_ldb, mem_ctx,
1924 if (!NT_STATUS_IS_OK(status)) {
1927 return NT_STATUS_NO_SUCH_USER;
1930 if (ldb_msg_add_empty(msg, "privilege", ldb_flag)) {
1931 return NT_STATUS_NO_MEMORY;
1934 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1937 r2.in.handle = &state->handle->wire_handle;
1939 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
1941 status = lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1942 if (!NT_STATUS_IS_OK(status)) {
1943 ZERO_STRUCTP(r2.out.rights);
1947 for (i=0;i<rights->count;i++) {
1948 if (sec_privilege_id(rights->names[i].string) == -1) {
1949 return NT_STATUS_NO_SUCH_PRIVILEGE;
1952 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1954 for (j=0;j<r2.out.rights->count;j++) {
1955 if (strcasecmp_m(r2.out.rights->names[j].string,
1956 rights->names[i].string) == 0) {
1960 if (j != r2.out.rights->count) continue;
1963 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
1964 if (ret != LDB_SUCCESS) {
1965 return NT_STATUS_NO_MEMORY;
1969 el = ldb_msg_find_element(msg, "privilege");
1971 return NT_STATUS_OK;
1974 ret = samdb_modify(state->sam_ldb, mem_ctx, msg);
1976 if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1977 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1979 DEBUG(3, ("Could not %s attributes from %s: %s",
1980 ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add",
1981 ldb_dn_linearize(mem_ctx, msg->dn), ldb_errstring(state->sam_ldb)));
1982 return NT_STATUS_UNEXPECTED_IO_ERROR;
1985 return NT_STATUS_OK;
1989 lsa_AddPrivilegesToAccount
1991 static NTSTATUS lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1992 struct lsa_AddPrivilegesToAccount *r)
1994 struct lsa_RightSet rights;
1995 struct dcesrv_handle *h;
1996 struct lsa_account_state *astate;
1999 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2003 rights.count = r->in.privs->count;
2004 rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
2005 if (rights.names == NULL) {
2006 return NT_STATUS_NO_MEMORY;
2008 for (i=0;i<rights.count;i++) {
2009 int id = r->in.privs->set[i].luid.low;
2010 if (r->in.privs->set[i].luid.high) {
2011 return NT_STATUS_NO_SUCH_PRIVILEGE;
2013 rights.names[i].string = sec_privilege_name(id);
2014 if (rights.names[i].string == NULL) {
2015 return NT_STATUS_NO_SUCH_PRIVILEGE;
2019 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2020 LDB_FLAG_MOD_ADD, astate->account_sid,
2026 lsa_RemovePrivilegesFromAccount
2028 static NTSTATUS lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2029 struct lsa_RemovePrivilegesFromAccount *r)
2031 struct lsa_RightSet *rights;
2032 struct dcesrv_handle *h;
2033 struct lsa_account_state *astate;
2036 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2040 rights = talloc(mem_ctx, struct lsa_RightSet);
2042 if (r->in.remove_all == 1 &&
2043 r->in.privs == NULL) {
2044 struct lsa_EnumAccountRights r2;
2047 r2.in.handle = &astate->policy->handle->wire_handle;
2048 r2.in.sid = astate->account_sid;
2049 r2.out.rights = rights;
2051 status = lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
2052 if (!NT_STATUS_IS_OK(status)) {
2056 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2057 LDB_FLAG_MOD_DELETE, astate->account_sid,
2061 if (r->in.remove_all != 0) {
2062 return NT_STATUS_INVALID_PARAMETER;
2065 rights->count = r->in.privs->count;
2066 rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
2067 if (rights->names == NULL) {
2068 return NT_STATUS_NO_MEMORY;
2070 for (i=0;i<rights->count;i++) {
2071 int id = r->in.privs->set[i].luid.low;
2072 if (r->in.privs->set[i].luid.high) {
2073 return NT_STATUS_NO_SUCH_PRIVILEGE;
2075 rights->names[i].string = sec_privilege_name(id);
2076 if (rights->names[i].string == NULL) {
2077 return NT_STATUS_NO_SUCH_PRIVILEGE;
2081 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2082 LDB_FLAG_MOD_DELETE, astate->account_sid,
2088 lsa_GetQuotasForAccount
2090 static NTSTATUS lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2091 struct lsa_GetQuotasForAccount *r)
2093 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2098 lsa_SetQuotasForAccount
2100 static NTSTATUS lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2101 struct lsa_SetQuotasForAccount *r)
2103 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2108 lsa_GetSystemAccessAccount
2110 static NTSTATUS lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2111 struct lsa_GetSystemAccessAccount *r)
2113 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2118 lsa_SetSystemAccessAccount
2120 static NTSTATUS lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2121 struct lsa_SetSystemAccessAccount *r)
2123 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2130 static NTSTATUS lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2131 struct lsa_CreateSecret *r)
2133 struct dcesrv_handle *policy_handle;
2134 struct lsa_policy_state *policy_state;
2135 struct lsa_secret_state *secret_state;
2136 struct dcesrv_handle *handle;
2137 struct ldb_message **msgs, *msg;
2139 const char *attrs[] = {
2147 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2148 ZERO_STRUCTP(r->out.sec_handle);
2150 policy_state = policy_handle->data;
2152 if (!r->in.name.string) {
2153 return NT_STATUS_INVALID_PARAMETER;
2156 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2157 if (!secret_state) {
2158 return NT_STATUS_NO_MEMORY;
2160 secret_state->policy = policy_state;
2162 msg = ldb_msg_new(mem_ctx);
2164 return NT_STATUS_NO_MEMORY;
2167 if (strncmp("G$", r->in.name.string, 2) == 0) {
2169 name = &r->in.name.string[2];
2170 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
2171 secret_state->global = True;
2173 if (strlen(name) < 1) {
2174 return NT_STATUS_INVALID_PARAMETER;
2177 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
2178 /* search for the secret record */
2179 ret = gendb_search(secret_state->sam_ldb,
2180 mem_ctx, policy_state->system_dn, &msgs, attrs,
2181 "(&(cn=%s)(objectclass=secret))",
2184 return NT_STATUS_OBJECT_NAME_COLLISION;
2188 DEBUG(0,("Failure searching for CN=%s: %s\n",
2189 name2, ldb_errstring(secret_state->sam_ldb)));
2190 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2193 msg->dn = ldb_dn_build_child(mem_ctx, "cn", name2, policy_state->system_dn);
2194 if (!name2 || !msg->dn) {
2195 return NT_STATUS_NO_MEMORY;
2198 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
2201 secret_state->global = False;
2203 name = r->in.name.string;
2204 if (strlen(name) < 1) {
2205 return NT_STATUS_INVALID_PARAMETER;
2208 secret_state->sam_ldb = talloc_reference(secret_state, secrets_db_connect(mem_ctx));
2209 /* search for the secret record */
2210 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2211 ldb_dn_explode(mem_ctx, "cn=LSA Secrets"),
2213 "(&(cn=%s)(objectclass=secret))",
2214 ldb_binary_encode_string(mem_ctx, name));
2216 return NT_STATUS_OBJECT_NAME_COLLISION;
2220 DEBUG(0,("Failure searching for CN=%s: %s\n",
2221 name, ldb_errstring(secret_state->sam_ldb)));
2222 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2225 msg->dn = ldb_dn_string_compose(mem_ctx, NULL, "cn=%s,cn=LSA Secrets", name);
2226 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
2229 /* pull in all the template attributes. Note this is always from the global samdb */
2230 ret = samdb_copy_template(secret_state->policy->sam_ldb, msg,
2231 "(&(cn=TemplateSecret)(objectclass=secretTemplate))", &errstr);
2233 DEBUG(0,("Failed to load TemplateSecret from samdb: %s\n",
2235 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2238 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
2240 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
2242 /* create the secret */
2243 ret = samdb_add(secret_state->sam_ldb, mem_ctx, msg);
2245 DEBUG(0,("Failed to create secret record %s: %s\n",
2246 ldb_dn_linearize(mem_ctx, msg->dn),
2247 ldb_errstring(secret_state->sam_ldb)));
2248 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2251 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2253 return NT_STATUS_NO_MEMORY;
2256 handle->data = talloc_steal(handle, secret_state);
2258 secret_state->access_mask = r->in.access_mask;
2259 secret_state->policy = talloc_reference(secret_state, policy_state);
2261 *r->out.sec_handle = handle->wire_handle;
2263 return NT_STATUS_OK;
2270 static NTSTATUS lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2271 struct lsa_OpenSecret *r)
2273 struct dcesrv_handle *policy_handle;
2275 struct lsa_policy_state *policy_state;
2276 struct lsa_secret_state *secret_state;
2277 struct dcesrv_handle *handle;
2278 struct ldb_message **msgs;
2279 const char *attrs[] = {
2287 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2288 ZERO_STRUCTP(r->out.sec_handle);
2289 policy_state = policy_handle->data;
2291 if (!r->in.name.string) {
2292 return NT_STATUS_INVALID_PARAMETER;
2295 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2296 if (!secret_state) {
2297 return NT_STATUS_NO_MEMORY;
2299 secret_state->policy = policy_state;
2301 if (strncmp("G$", r->in.name.string, 2) == 0) {
2302 name = &r->in.name.string[2];
2303 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
2304 secret_state->global = True;
2306 if (strlen(name) < 1) {
2307 return NT_STATUS_INVALID_PARAMETER;
2310 /* search for the secret record */
2311 ret = gendb_search(secret_state->sam_ldb,
2312 mem_ctx, policy_state->system_dn, &msgs, attrs,
2313 "(&(cn=%s Secret)(objectclass=secret))",
2314 ldb_binary_encode_string(mem_ctx, name));
2316 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2320 DEBUG(0,("Found %d records matching DN %s\n", ret,
2321 ldb_dn_linearize(mem_ctx, policy_state->system_dn)));
2322 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2326 secret_state->sam_ldb = talloc_reference(secret_state, secrets_db_connect(mem_ctx));
2328 secret_state->global = False;
2329 name = r->in.name.string;
2330 if (strlen(name) < 1) {
2331 return NT_STATUS_INVALID_PARAMETER;
2334 /* search for the secret record */
2335 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2336 ldb_dn_explode(mem_ctx, "cn=LSA Secrets"),
2338 "(&(cn=%s)(objectclass=secret))",
2339 ldb_binary_encode_string(mem_ctx, name));
2341 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2345 DEBUG(0,("Found %d records matching DN %s\n", ret,
2346 ldb_dn_linearize(mem_ctx, policy_state->system_dn)));
2347 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2351 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
2353 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2355 return NT_STATUS_NO_MEMORY;
2358 handle->data = talloc_steal(handle, secret_state);
2360 secret_state->access_mask = r->in.access_mask;
2361 secret_state->policy = talloc_reference(secret_state, policy_state);
2363 *r->out.sec_handle = handle->wire_handle;
2365 return NT_STATUS_OK;
2372 static NTSTATUS lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2373 struct lsa_SetSecret *r)
2376 struct dcesrv_handle *h;
2377 struct lsa_secret_state *secret_state;
2378 struct ldb_message *msg;
2379 DATA_BLOB session_key;
2380 DATA_BLOB crypt_secret, secret;
2383 NTSTATUS status = NT_STATUS_OK;
2385 struct timeval now = timeval_current();
2386 NTTIME nt_now = timeval_to_nttime(&now);
2388 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2390 secret_state = h->data;
2392 msg = ldb_msg_new(mem_ctx);
2394 return NT_STATUS_NO_MEMORY;
2397 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
2399 return NT_STATUS_NO_MEMORY;
2401 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2402 if (!NT_STATUS_IS_OK(status)) {
2406 if (r->in.old_val) {
2408 crypt_secret.data = r->in.old_val->data;
2409 crypt_secret.length = r->in.old_val->size;
2411 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2412 if (!NT_STATUS_IS_OK(status)) {
2416 val.data = secret.data;
2417 val.length = secret.length;
2420 if (samdb_msg_add_value(secret_state->sam_ldb,
2421 mem_ctx, msg, "priorSecret", &val) != 0) {
2422 return NT_STATUS_NO_MEMORY;
2425 /* set old value mtime */
2426 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2427 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
2428 return NT_STATUS_NO_MEMORY;
2431 if (!r->in.new_val) {
2432 /* This behaviour varies depending of if this is a local, or a global secret... */
2433 if (secret_state->global) {
2434 /* set old value mtime */
2435 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2436 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2437 return NT_STATUS_NO_MEMORY;
2440 if (samdb_msg_add_delete(secret_state->sam_ldb,
2441 mem_ctx, msg, "secret")) {
2442 return NT_STATUS_NO_MEMORY;
2444 if (samdb_msg_add_delete(secret_state->sam_ldb,
2445 mem_ctx, msg, "lastSetTime")) {
2446 return NT_STATUS_NO_MEMORY;
2452 if (r->in.new_val) {
2454 crypt_secret.data = r->in.new_val->data;
2455 crypt_secret.length = r->in.new_val->size;
2457 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2458 if (!NT_STATUS_IS_OK(status)) {
2462 val.data = secret.data;
2463 val.length = secret.length;
2466 if (samdb_msg_add_value(secret_state->sam_ldb,
2467 mem_ctx, msg, "secret", &val) != 0) {
2468 return NT_STATUS_NO_MEMORY;
2471 /* set new value mtime */
2472 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2473 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2474 return NT_STATUS_NO_MEMORY;
2477 /* If the old value is not set, then migrate the
2478 * current value to the old value */
2479 if (!r->in.old_val) {
2480 const struct ldb_val *new_val;
2481 NTTIME last_set_time;
2482 struct ldb_message **res;
2483 const char *attrs[] = {
2489 /* search for the secret record */
2490 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
2491 secret_state->secret_dn, &res, attrs);
2493 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2497 DEBUG(0,("Found %d records matching dn=%s\n", ret,
2498 ldb_dn_linearize(mem_ctx, secret_state->secret_dn)));
2499 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2502 new_val = ldb_msg_find_ldb_val(res[0], "secret");
2503 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2507 if (samdb_msg_add_value(secret_state->sam_ldb,
2508 mem_ctx, msg, "priorSecret",
2510 return NT_STATUS_NO_MEMORY;
2514 /* set new value mtime */
2515 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2516 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2517 mem_ctx, msg, "priorSetTime", last_set_time) != 0) {
2518 return NT_STATUS_NO_MEMORY;
2524 /* modify the samdb record */
2525 ret = samdb_replace(secret_state->sam_ldb, mem_ctx, msg);
2527 /* we really need samdb.c to return NTSTATUS */
2528 return NT_STATUS_UNSUCCESSFUL;
2531 return NT_STATUS_OK;
2538 static NTSTATUS lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2539 struct lsa_QuerySecret *r)
2541 struct dcesrv_handle *h;
2542 struct lsa_secret_state *secret_state;
2543 struct ldb_message *msg;
2544 DATA_BLOB session_key;
2545 DATA_BLOB crypt_secret, secret;
2547 struct ldb_message **res;
2548 const char *attrs[] = {
2558 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2560 secret_state = h->data;
2562 /* pull all the user attributes */
2563 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2564 secret_state->secret_dn, &res, attrs);
2566 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2570 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2571 if (!NT_STATUS_IS_OK(nt_status)) {
2575 if (r->in.old_val) {
2576 const struct ldb_val *prior_val;
2577 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2578 if (!r->out.old_val) {
2579 return NT_STATUS_NO_MEMORY;
2582 prior_val = ldb_msg_find_ldb_val(res[0], "priorSecret");
2584 if (prior_val && prior_val->length) {
2585 secret.data = prior_val->data;
2586 secret.length = prior_val->length;
2588 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2589 if (!crypt_secret.length) {
2590 return NT_STATUS_NO_MEMORY;
2592 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2593 if (!r->out.old_val->buf) {
2594 return NT_STATUS_NO_MEMORY;
2596 r->out.old_val->buf->size = crypt_secret.length;
2597 r->out.old_val->buf->length = crypt_secret.length;
2598 r->out.old_val->buf->data = crypt_secret.data;
2602 if (r->in.old_mtime) {
2603 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2604 if (!r->out.old_mtime) {
2605 return NT_STATUS_NO_MEMORY;
2607 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
2610 if (r->in.new_val) {
2611 const struct ldb_val *new_val;
2612 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2613 if (!r->out.new_val) {
2614 return NT_STATUS_NO_MEMORY;
2618 new_val = ldb_msg_find_ldb_val(res[0], "secret");
2620 if (new_val && new_val->length) {
2621 secret.data = new_val->data;
2622 secret.length = new_val->length;
2624 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2625 if (!crypt_secret.length) {
2626 return NT_STATUS_NO_MEMORY;
2628 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2629 if (!r->out.new_val->buf) {
2630 return NT_STATUS_NO_MEMORY;
2632 r->out.new_val->buf->length = crypt_secret.length;
2633 r->out.new_val->buf->size = crypt_secret.length;
2634 r->out.new_val->buf->data = crypt_secret.data;
2638 if (r->in.new_mtime) {
2639 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2640 if (!r->out.new_mtime) {
2641 return NT_STATUS_NO_MEMORY;
2643 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2646 return NT_STATUS_OK;
2653 static NTSTATUS lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
2654 TALLOC_CTX *mem_ctx,
2655 struct lsa_LookupPrivValue *r)
2657 struct dcesrv_handle *h;
2658 struct lsa_policy_state *state;
2661 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2665 id = sec_privilege_id(r->in.name->string);
2667 return NT_STATUS_NO_SUCH_PRIVILEGE;
2670 r->out.luid->low = id;
2671 r->out.luid->high = 0;
2673 return NT_STATUS_OK;
2680 static NTSTATUS lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
2681 TALLOC_CTX *mem_ctx,
2682 struct lsa_LookupPrivName *r)
2684 struct dcesrv_handle *h;
2685 struct lsa_policy_state *state;
2686 const char *privname;
2688 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2692 if (r->in.luid->high != 0) {
2693 return NT_STATUS_NO_SUCH_PRIVILEGE;
2696 privname = sec_privilege_name(r->in.luid->low);
2697 if (privname == NULL) {
2698 return NT_STATUS_NO_SUCH_PRIVILEGE;
2701 r->out.name = talloc(mem_ctx, struct lsa_StringLarge);
2702 if (r->out.name == NULL) {
2703 return NT_STATUS_NO_MEMORY;
2705 r->out.name->string = privname;
2707 return NT_STATUS_OK;
2712 lsa_LookupPrivDisplayName
2714 static NTSTATUS lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
2715 TALLOC_CTX *mem_ctx,
2716 struct lsa_LookupPrivDisplayName *r)
2718 struct dcesrv_handle *h;
2719 struct lsa_policy_state *state;
2722 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2726 id = sec_privilege_id(r->in.name->string);
2728 return NT_STATUS_NO_SUCH_PRIVILEGE;
2731 r->out.disp_name = talloc(mem_ctx, struct lsa_StringLarge);
2732 if (r->out.disp_name == NULL) {
2733 return NT_STATUS_NO_MEMORY;
2736 r->out.disp_name->string = sec_privilege_display_name(id, r->in.language_id);
2737 if (r->out.disp_name->string == NULL) {
2738 return NT_STATUS_INTERNAL_ERROR;
2741 return NT_STATUS_OK;
2748 static NTSTATUS lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2749 struct lsa_DeleteObject *r)
2751 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2756 lsa_EnumAccountsWithUserRight
2758 static NTSTATUS lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
2759 TALLOC_CTX *mem_ctx,
2760 struct lsa_EnumAccountsWithUserRight *r)
2762 struct dcesrv_handle *h;
2763 struct lsa_policy_state *state;
2765 struct ldb_message **res;
2766 const char * const attrs[] = { "objectSid", NULL};
2767 const char *privname;
2769 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2773 if (r->in.name == NULL) {
2774 return NT_STATUS_NO_SUCH_PRIVILEGE;
2777 privname = r->in.name->string;
2778 if (sec_privilege_id(privname) == -1) {
2779 return NT_STATUS_NO_SUCH_PRIVILEGE;
2782 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
2783 "privilege=%s", privname);
2785 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2788 return NT_STATUS_NO_MORE_ENTRIES;
2791 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2792 if (r->out.sids->sids == NULL) {
2793 return NT_STATUS_NO_MEMORY;
2795 for (i=0;i<ret;i++) {
2796 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2797 res[i], "objectSid");
2798 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2800 r->out.sids->num_sids = ret;
2802 return NT_STATUS_OK;
2807 lsa_AddAccountRights
2809 static NTSTATUS lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
2810 TALLOC_CTX *mem_ctx,
2811 struct lsa_AddAccountRights *r)
2813 struct dcesrv_handle *h;
2814 struct lsa_policy_state *state;
2816 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2820 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2822 r->in.sid, r->in.rights);
2827 lsa_RemoveAccountRights
2829 static NTSTATUS lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
2830 TALLOC_CTX *mem_ctx,
2831 struct lsa_RemoveAccountRights *r)
2833 struct dcesrv_handle *h;
2834 struct lsa_policy_state *state;
2836 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2840 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2841 LDB_FLAG_MOD_DELETE,
2842 r->in.sid, r->in.rights);
2847 lsa_StorePrivateData
2849 static NTSTATUS lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2850 struct lsa_StorePrivateData *r)
2852 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2857 lsa_RetrievePrivateData
2859 static NTSTATUS lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2860 struct lsa_RetrievePrivateData *r)
2862 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2869 static NTSTATUS lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2870 struct lsa_GetUserName *r)
2872 NTSTATUS status = NT_STATUS_OK;
2873 const char *account_name;
2874 const char *authority_name;
2875 struct lsa_String *_account_name;
2876 struct lsa_StringPointer *_authority_name = NULL;
2878 /* this is what w2k3 does */
2879 r->out.account_name = r->in.account_name;
2880 r->out.authority_name = r->in.authority_name;
2882 if (r->in.account_name && r->in.account_name->string) {
2883 return NT_STATUS_INVALID_PARAMETER;
2886 if (r->in.authority_name &&
2887 r->in.authority_name->string &&
2888 r->in.authority_name->string->string) {
2889 return NT_STATUS_INVALID_PARAMETER;
2892 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
2893 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
2895 _account_name = talloc(mem_ctx, struct lsa_String);
2896 NT_STATUS_HAVE_NO_MEMORY(_account_name);
2897 _account_name->string = account_name;
2899 if (r->in.authority_name) {
2900 _authority_name = talloc(mem_ctx, struct lsa_StringPointer);
2901 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
2902 _authority_name->string = talloc(mem_ctx, struct lsa_String);
2903 NT_STATUS_HAVE_NO_MEMORY(_authority_name->string);
2904 _authority_name->string->string = authority_name;
2907 r->out.account_name = _account_name;
2908 r->out.authority_name = _authority_name;
2916 static NTSTATUS lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
2917 TALLOC_CTX *mem_ctx,
2918 struct lsa_SetInfoPolicy2 *r)
2920 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2924 lsa_QueryDomainInformationPolicy
2926 static NTSTATUS lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2927 TALLOC_CTX *mem_ctx,
2928 struct lsa_QueryDomainInformationPolicy *r)
2930 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2934 lsa_SetDomInfoPolicy
2936 static NTSTATUS lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2937 TALLOC_CTX *mem_ctx,
2938 struct lsa_SetDomainInformationPolicy *r)
2940 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2946 static NTSTATUS lsa_TestCall(struct dcesrv_call_state *dce_call,
2947 TALLOC_CTX *mem_ctx,
2948 struct lsa_TestCall *r)
2950 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2954 lookup a SID for 1 name
2956 static NTSTATUS lsa_lookup_name(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
2957 const char *name, struct dom_sid **sid, uint32_t *atype)
2960 struct ldb_message **res;
2961 const char * const attrs[] = { "objectSid", "sAMAccountType", NULL};
2964 p = strchr_m(name, '\\');
2966 /* TODO: properly parse the domain prefix here, and use it to
2971 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs, "sAMAccountName=%s", ldb_binary_encode_string(mem_ctx, name));
2973 *sid = samdb_result_dom_sid(mem_ctx, res[0], "objectSid");
2975 return NT_STATUS_INVALID_SID;
2978 *atype = samdb_result_uint(res[0], "sAMAccountType", 0);
2980 return NT_STATUS_OK;
2983 /* need to add a call into sidmap to check for a allocated sid */
2985 return NT_STATUS_INVALID_SID;
2992 static NTSTATUS lsa_LookupNames4(struct dcesrv_call_state *dce_call,
2993 TALLOC_CTX *mem_ctx,
2994 struct lsa_LookupNames4 *r)
2996 struct lsa_policy_state *state;
2998 NTSTATUS status = NT_STATUS_OK;
3000 status = lsa_get_policy_state(dce_call, mem_ctx, &state);
3001 if (!NT_STATUS_IS_OK(status)) {
3005 r->out.domains = NULL;
3007 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
3008 if (r->out.domains == NULL) {
3009 return NT_STATUS_NO_MEMORY;
3012 r->out.sids = talloc_zero(mem_ctx, struct lsa_TransSidArray3);
3013 if (r->out.sids == NULL) {
3014 return NT_STATUS_NO_MEMORY;
3019 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid3,
3021 if (r->out.sids->sids == NULL) {
3022 return NT_STATUS_NO_MEMORY;
3025 for (i=0;i<r->in.num_names;i++) {
3026 const char *name = r->in.names[i].string;
3027 struct dom_sid *sid;
3028 uint32_t atype, rtype, sid_index;
3031 r->out.sids->count++;
3034 r->out.sids->sids[i].sid_type = SID_NAME_UNKNOWN;
3035 r->out.sids->sids[i].sid = NULL;
3036 r->out.sids->sids[i].sid_index = 0xFFFFFFFF;
3037 r->out.sids->sids[i].unknown = 0;
3039 status2 = lsa_lookup_name(state, mem_ctx, name, &sid, &atype);
3040 if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
3041 status = STATUS_SOME_UNMAPPED;
3045 rtype = samdb_atype_map(atype);
3046 if (rtype == SID_NAME_UNKNOWN) {
3047 status = STATUS_SOME_UNMAPPED;
3051 status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
3052 if (!NT_STATUS_IS_OK(status2)) {
3056 r->out.sids->sids[i].sid_type = rtype;
3057 r->out.sids->sids[i].sid = sid;
3058 r->out.sids->sids[i].sid_index = sid_index;
3059 r->out.sids->sids[i].unknown = 0;
3068 static NTSTATUS lsa_LookupNames3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3069 struct lsa_LookupNames3 *r)
3071 struct lsa_LookupNames4 r2;
3073 struct dcesrv_handle *h;
3074 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3076 r2.in.num_names = r->in.num_names;
3077 r2.in.names = r->in.names;
3078 r2.in.sids = r->in.sids;
3079 r2.in.count = r->in.count;
3080 r2.in.unknown1 = r->in.unknown1;
3081 r2.in.unknown2 = r->in.unknown2;
3082 r2.out.domains = r->out.domains;
3083 r2.out.sids = r->out.sids;
3084 r2.out.count = r->out.count;
3086 status = lsa_LookupNames4(dce_call, mem_ctx, &r2);
3087 if (dce_call->fault_code != 0) {
3091 r->out.domains = r2.out.domains;
3092 r->out.sids = r2.out.sids;
3093 r->out.count = r2.out.count;
3100 static NTSTATUS lsa_LookupNames2(struct dcesrv_call_state *dce_call,
3101 TALLOC_CTX *mem_ctx,
3102 struct lsa_LookupNames2 *r)
3104 struct lsa_policy_state *state;
3105 struct dcesrv_handle *h;
3107 NTSTATUS status = NT_STATUS_OK;
3109 r->out.domains = NULL;
3111 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3115 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
3116 if (r->out.domains == NULL) {
3117 return NT_STATUS_NO_MEMORY;
3120 r->out.sids = talloc_zero(mem_ctx, struct lsa_TransSidArray2);
3121 if (r->out.sids == NULL) {
3122 return NT_STATUS_NO_MEMORY;
3127 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid2,
3129 if (r->out.sids->sids == NULL) {
3130 return NT_STATUS_NO_MEMORY;
3133 for (i=0;i<r->in.num_names;i++) {
3134 const char *name = r->in.names[i].string;
3135 struct dom_sid *sid;
3136 uint32_t atype, rtype, sid_index;
3139 r->out.sids->count++;
3142 r->out.sids->sids[i].sid_type = SID_NAME_UNKNOWN;
3143 r->out.sids->sids[i].rid = 0xFFFFFFFF;
3144 r->out.sids->sids[i].sid_index = 0xFFFFFFFF;
3145 r->out.sids->sids[i].unknown = 0;
3147 status2 = lsa_lookup_name(state, mem_ctx, name, &sid, &atype);
3148 if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
3149 status = STATUS_SOME_UNMAPPED;
3153 rtype = samdb_atype_map(atype);
3154 if (rtype == SID_NAME_UNKNOWN) {
3155 status = STATUS_SOME_UNMAPPED;
3159 status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
3160 if (!NT_STATUS_IS_OK(status2)) {
3164 r->out.sids->sids[i].sid_type = rtype;
3165 r->out.sids->sids[i].rid = sid->sub_auths[sid->num_auths-1];
3166 r->out.sids->sids[i].sid_index = sid_index;
3167 r->out.sids->sids[i].unknown = 0;
3176 static NTSTATUS lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3177 struct lsa_LookupNames *r)
3179 struct lsa_LookupNames2 r2;
3183 r2.in.handle = r->in.handle;
3184 r2.in.num_names = r->in.num_names;
3185 r2.in.names = r->in.names;
3187 r2.in.level = r->in.level;
3188 r2.in.count = r->in.count;
3191 r2.out.count = r->out.count;
3193 status = lsa_LookupNames2(dce_call, mem_ctx, &r2);
3194 if (dce_call->fault_code != 0) {
3198 r->out.domains = r2.out.domains;
3199 r->out.sids = talloc(mem_ctx, struct lsa_TransSidArray);
3200 if (r->out.sids == NULL) {
3201 return NT_STATUS_NO_MEMORY;
3203 r->out.sids->count = r2.out.sids->count;
3204 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid,
3205 r->out.sids->count);
3206 if (r->out.sids->sids == NULL) {
3207 return NT_STATUS_NO_MEMORY;
3209 for (i=0;i<r->out.sids->count;i++) {
3210 r->out.sids->sids[i].sid_type = r2.out.sids->sids[i].sid_type;
3211 r->out.sids->sids[i].rid = r2.out.sids->sids[i].rid;
3212 r->out.sids->sids[i].sid_index = r2.out.sids->sids[i].sid_index;
3221 static NTSTATUS lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3222 struct lsa_CREDRWRITE *r)
3224 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3231 static NTSTATUS lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3232 struct lsa_CREDRREAD *r)
3234 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3241 static NTSTATUS lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3242 struct lsa_CREDRENUMERATE *r)
3244 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3249 lsa_CREDRWRITEDOMAINCREDENTIALS
3251 static NTSTATUS lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3252 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3254 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3259 lsa_CREDRREADDOMAINCREDENTIALS
3261 static NTSTATUS lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3262 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3264 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3271 static NTSTATUS lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3272 struct lsa_CREDRDELETE *r)
3274 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3279 lsa_CREDRGETTARGETINFO
3281 static NTSTATUS lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3282 struct lsa_CREDRGETTARGETINFO *r)
3284 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3289 lsa_CREDRPROFILELOADED
3291 static NTSTATUS lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3292 struct lsa_CREDRPROFILELOADED *r)
3294 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3299 lsa_CREDRGETSESSIONTYPES
3301 static NTSTATUS lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3302 struct lsa_CREDRGETSESSIONTYPES *r)
3304 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3309 lsa_LSARREGISTERAUDITEVENT
3311 static NTSTATUS lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3312 struct lsa_LSARREGISTERAUDITEVENT *r)
3314 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3319 lsa_LSARGENAUDITEVENT
3321 static NTSTATUS lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3322 struct lsa_LSARGENAUDITEVENT *r)
3324 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3329 lsa_LSARUNREGISTERAUDITEVENT
3331 static NTSTATUS lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3332 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3334 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3339 lsa_LSARQUERYFORESTTRUSTINFORMATION
3341 static NTSTATUS lsa_LSARQUERYFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3342 struct lsa_LSARQUERYFORESTTRUSTINFORMATION *r)
3344 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3349 lsa_LSARSETFORESTTRUSTINFORMATION
3351 static NTSTATUS lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3352 struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
3354 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3361 static NTSTATUS lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3362 struct lsa_CREDRRENAME *r)
3364 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3370 lsa_LSAROPENPOLICYSCE
3372 static NTSTATUS lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3373 struct lsa_LSAROPENPOLICYSCE *r)
3375 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3380 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
3382 static NTSTATUS lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3383 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
3385 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3390 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
3392 static NTSTATUS lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3393 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
3395 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3400 lsa_LSARADTREPORTSECURITYEVENT
3402 static NTSTATUS lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3403 struct lsa_LSARADTREPORTSECURITYEVENT *r)
3405 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3409 /* include the generated boilerplate */
3410 #include "librpc/gen_ndr/ndr_lsa_s.c"
3414 /*****************************************
3415 NOTE! The remaining calls below were
3416 removed in w2k3, so the DCESRV_FAULT()
3417 replies are the correct implementation. Do
3418 not try and fill these in with anything else
3419 ******************************************/
3422 dssetup_DsRoleDnsNameToFlatName
3424 static WERROR dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3425 struct dssetup_DsRoleDnsNameToFlatName *r)
3427 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3432 dssetup_DsRoleDcAsDc
3434 static WERROR dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3435 struct dssetup_DsRoleDcAsDc *r)
3437 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3442 dssetup_DsRoleDcAsReplica
3444 static WERROR dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3445 struct dssetup_DsRoleDcAsReplica *r)
3447 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3452 dssetup_DsRoleDemoteDc
3454 static WERROR dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3455 struct dssetup_DsRoleDemoteDc *r)
3457 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3462 dssetup_DsRoleGetDcOperationProgress
3464 static WERROR dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3465 struct dssetup_DsRoleGetDcOperationProgress *r)
3467 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3472 dssetup_DsRoleGetDcOperationResults
3474 static WERROR dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3475 struct dssetup_DsRoleGetDcOperationResults *r)
3477 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3482 dssetup_DsRoleCancel
3484 static WERROR dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3485 struct dssetup_DsRoleCancel *r)
3487 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3492 dssetup_DsRoleServerSaveStateForUpgrade
3494 static WERROR dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3495 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
3497 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3502 dssetup_DsRoleUpgradeDownlevelServer
3504 static WERROR dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3505 struct dssetup_DsRoleUpgradeDownlevelServer *r)
3507 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3512 dssetup_DsRoleAbortDownlevelServerUpgrade
3514 static WERROR dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3515 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
3517 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3521 /* include the generated boilerplate */
3522 #include "librpc/gen_ndr/ndr_dssetup_s.c"
3524 NTSTATUS dcerpc_server_lsa_init(void)
3528 ret = dcerpc_server_dssetup_init();
3529 if (!NT_STATUS_IS_OK(ret)) {
3532 ret = dcerpc_server_lsarpc_init();
3533 if (!NT_STATUS_IS_OK(ret)) {