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 "param/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 struct ldb_dn *domain_dn;
56 struct ldb_dn *forest_dn;
57 struct ldb_dn *builtin_dn;
58 struct ldb_dn *system_dn;
59 const char *domain_name;
60 const char *domain_dns;
61 const char *forest_dns;
62 struct dom_sid *domain_sid;
63 struct GUID domain_guid;
64 struct dom_sid *builtin_sid;
70 state associated with a lsa_OpenAccount() operation
72 struct lsa_account_state {
73 struct lsa_policy_state *policy;
75 struct dom_sid *account_sid;
80 state associated with a lsa_OpenSecret() operation
82 struct lsa_secret_state {
83 struct lsa_policy_state *policy;
85 struct ldb_dn *secret_dn;
86 struct ldb_context *sam_ldb;
91 state associated with a lsa_OpenTrustedDomain() operation
93 struct lsa_trusted_domain_state {
94 struct lsa_policy_state *policy;
96 struct ldb_dn *trusted_domain_dn;
99 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
101 struct lsa_EnumAccountRights *r);
103 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
105 struct lsa_policy_state *state,
108 const struct lsa_RightSet *rights);
113 static NTSTATUS dcesrv_lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
116 struct dcesrv_handle *h;
118 *r->out.handle = *r->in.handle;
120 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
124 ZERO_STRUCTP(r->out.handle);
133 static NTSTATUS dcesrv_lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
134 struct lsa_Delete *r)
136 struct dcesrv_handle *h;
139 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
140 if (h->wire_handle.handle_type == LSA_HANDLE_SECRET) {
141 struct lsa_secret_state *secret_state = h->data;
142 ret = samdb_delete(secret_state->sam_ldb, mem_ctx, secret_state->secret_dn);
145 return NT_STATUS_INVALID_HANDLE;
149 } else if (h->wire_handle.handle_type == LSA_HANDLE_TRUSTED_DOMAIN) {
150 struct lsa_trusted_domain_state *trusted_domain_state = h->data;
151 ret = samdb_delete(trusted_domain_state->policy->sam_ldb, mem_ctx,
152 trusted_domain_state->trusted_domain_dn);
155 return NT_STATUS_INVALID_HANDLE;
159 } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
160 struct lsa_RightSet *rights;
161 struct lsa_account_state *astate;
162 struct lsa_EnumAccountRights r2;
165 rights = talloc(mem_ctx, struct lsa_RightSet);
167 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
171 r2.in.handle = &astate->policy->handle->wire_handle;
172 r2.in.sid = astate->account_sid;
173 r2.out.rights = rights;
175 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
176 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
180 if (!NT_STATUS_IS_OK(status)) {
184 status = dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
185 LDB_FLAG_MOD_DELETE, astate->account_sid,
187 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
191 if (!NT_STATUS_IS_OK(status)) {
196 return NT_STATUS_INVALID_HANDLE;
203 static NTSTATUS dcesrv_lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
204 struct lsa_EnumPrivs *r)
206 struct dcesrv_handle *h;
207 struct lsa_policy_state *state;
209 const char *privname;
211 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
215 i = *r->in.resume_handle;
218 while ((privname = sec_privilege_name(i)) &&
219 r->out.privs->count < r->in.max_count) {
220 struct lsa_PrivEntry *e;
222 r->out.privs->privs = talloc_realloc(r->out.privs,
224 struct lsa_PrivEntry,
225 r->out.privs->count+1);
226 if (r->out.privs->privs == NULL) {
227 return NT_STATUS_NO_MEMORY;
229 e = &r->out.privs->privs[r->out.privs->count];
232 e->name.string = privname;
233 r->out.privs->count++;
237 *r->out.resume_handle = i;
246 static NTSTATUS dcesrv_lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
247 struct lsa_QuerySecurity *r)
249 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
256 static NTSTATUS dcesrv_lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
257 struct lsa_SetSecObj *r)
259 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
266 static NTSTATUS dcesrv_lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
267 struct lsa_ChangePassword *r)
269 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
272 static NTSTATUS dcesrv_lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
273 struct lsa_policy_state **_state)
275 struct lsa_policy_state *state;
276 struct ldb_dn *partitions_basedn;
277 struct ldb_result *dom_res;
278 const char *dom_attrs[] = {
285 struct ldb_result *ref_res;
286 struct ldb_result *forest_ref_res;
287 const char *ref_attrs[] = {
294 state = talloc(mem_ctx, struct lsa_policy_state);
296 return NT_STATUS_NO_MEMORY;
299 /* make sure the sam database is accessible */
300 state->sam_ldb = samdb_connect(state, dce_call->conn->auth_state.session_info);
301 if (state->sam_ldb == NULL) {
302 return NT_STATUS_INVALID_SYSTEM_SERVICE;
305 partitions_basedn = samdb_partitions_dn(state->sam_ldb, mem_ctx);
307 state->sidmap = sidmap_open(state);
308 if (state->sidmap == NULL) {
309 return NT_STATUS_INVALID_SYSTEM_SERVICE;
312 /* work out the domain_dn - useful for so many calls its worth
314 state->domain_dn = samdb_base_dn(state->sam_ldb);
315 if (!state->domain_dn) {
316 return NT_STATUS_NO_MEMORY;
319 /* work out the forest root_dn - useful for so many calls its worth
321 state->forest_dn = samdb_root_dn(state->sam_ldb);
322 if (!state->forest_dn) {
323 return NT_STATUS_NO_MEMORY;
326 ret = ldb_search(state->sam_ldb, state->domain_dn, LDB_SCOPE_BASE, NULL, dom_attrs, &dom_res);
328 if (ret != LDB_SUCCESS) {
329 return NT_STATUS_INVALID_SYSTEM_SERVICE;
331 talloc_steal(mem_ctx, dom_res);
332 if (dom_res->count != 1) {
333 return NT_STATUS_NO_SUCH_DOMAIN;
336 state->domain_sid = samdb_result_dom_sid(state, dom_res->msgs[0], "objectSid");
337 if (!state->domain_sid) {
338 return NT_STATUS_NO_SUCH_DOMAIN;
341 state->domain_guid = samdb_result_guid(dom_res->msgs[0], "objectGUID");
342 if (!state->domain_sid) {
343 return NT_STATUS_NO_SUCH_DOMAIN;
346 state->mixed_domain = ldb_msg_find_attr_as_uint(dom_res->msgs[0], "nTMixedDomain", 0);
348 talloc_free(dom_res);
350 ret = ldb_search_exp_fmt(state->sam_ldb, state, &ref_res,
351 partitions_basedn, LDB_SCOPE_SUBTREE, ref_attrs,
352 "(&(objectclass=crossRef)(ncName=%s))",
353 ldb_dn_get_linearized(state->domain_dn));
355 if (ret != LDB_SUCCESS) {
356 talloc_free(ref_res);
357 return NT_STATUS_INVALID_SYSTEM_SERVICE;
359 if (ref_res->count != 1) {
360 talloc_free(ref_res);
361 return NT_STATUS_NO_SUCH_DOMAIN;
364 state->domain_name = ldb_msg_find_attr_as_string(ref_res->msgs[0], "nETBIOSName", NULL);
365 if (!state->domain_name) {
366 talloc_free(ref_res);
367 return NT_STATUS_NO_SUCH_DOMAIN;
369 talloc_steal(state, state->domain_name);
371 state->domain_dns = ldb_msg_find_attr_as_string(ref_res->msgs[0], "dnsRoot", NULL);
372 if (!state->domain_dns) {
373 talloc_free(ref_res);
374 return NT_STATUS_NO_SUCH_DOMAIN;
376 talloc_steal(state, state->domain_dns);
378 talloc_free(ref_res);
380 ret = ldb_search_exp_fmt(state->sam_ldb, state, &forest_ref_res,
381 partitions_basedn, LDB_SCOPE_SUBTREE, ref_attrs,
382 "(&(objectclass=crossRef)(ncName=%s))",
383 ldb_dn_get_linearized(state->forest_dn));
385 if (ret != LDB_SUCCESS) {
386 talloc_free(forest_ref_res);
387 return NT_STATUS_INVALID_SYSTEM_SERVICE;
389 if (forest_ref_res->count != 1) {
390 talloc_free(forest_ref_res);
391 return NT_STATUS_NO_SUCH_DOMAIN;
394 state->forest_dns = ldb_msg_find_attr_as_string(forest_ref_res->msgs[0], "dnsRoot", NULL);
395 if (!state->forest_dns) {
396 talloc_free(forest_ref_res);
397 return NT_STATUS_NO_SUCH_DOMAIN;
399 talloc_steal(state, state->forest_dns);
401 talloc_free(forest_ref_res);
403 /* work out the builtin_dn - useful for so many calls its worth
405 state->builtin_dn = samdb_search_dn(state->sam_ldb, state, state->domain_dn, "(objectClass=builtinDomain)");
406 if (!state->builtin_dn) {
407 return NT_STATUS_NO_SUCH_DOMAIN;
410 /* work out the system_dn - useful for so many calls its worth
412 state->system_dn = samdb_search_dn(state->sam_ldb, state,
413 state->domain_dn, "(&(objectClass=container)(cn=System))");
414 if (!state->system_dn) {
415 return NT_STATUS_NO_SUCH_DOMAIN;
418 state->builtin_sid = dom_sid_parse_talloc(state, SID_BUILTIN);
419 if (!state->builtin_sid) {
420 return NT_STATUS_NO_SUCH_DOMAIN;
429 dssetup_DsRoleGetPrimaryDomainInformation
431 This is not an LSA call, but is the only call left on the DSSETUP
432 pipe (after the pipe was truncated), and needs lsa_get_policy_state
434 static WERROR dcesrv_dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state *dce_call,
436 struct dssetup_DsRoleGetPrimaryDomainInformation *r)
438 union dssetup_DsRoleInfo *info;
440 info = talloc(mem_ctx, union dssetup_DsRoleInfo);
441 W_ERROR_HAVE_NO_MEMORY(info);
443 switch (r->in.level) {
444 case DS_ROLE_BASIC_INFORMATION:
446 enum dssetup_DsRole role = DS_ROLE_STANDALONE_SERVER;
448 const char *domain = NULL;
449 const char *dns_domain = NULL;
450 const char *forest = NULL;
451 struct GUID domain_guid;
452 struct lsa_policy_state *state;
454 NTSTATUS status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
455 if (!NT_STATUS_IS_OK(status)) {
456 return ntstatus_to_werror(status);
459 ZERO_STRUCT(domain_guid);
461 switch (lp_server_role()) {
462 case ROLE_STANDALONE:
463 role = DS_ROLE_STANDALONE_SERVER;
465 case ROLE_DOMAIN_MEMBER:
466 role = DS_ROLE_MEMBER_SERVER;
468 case ROLE_DOMAIN_CONTROLLER:
469 if (samdb_is_pdc(state->sam_ldb)) {
470 role = DS_ROLE_PRIMARY_DC;
472 role = DS_ROLE_BACKUP_DC;
477 switch (lp_server_role()) {
478 case ROLE_STANDALONE:
479 domain = talloc_strdup(mem_ctx, lp_workgroup());
480 W_ERROR_HAVE_NO_MEMORY(domain);
482 case ROLE_DOMAIN_MEMBER:
483 domain = talloc_strdup(mem_ctx, lp_workgroup());
484 W_ERROR_HAVE_NO_MEMORY(domain);
485 /* TODO: what is with dns_domain and forest and guid? */
487 case ROLE_DOMAIN_CONTROLLER:
488 flags = DS_ROLE_PRIMARY_DS_RUNNING;
490 if (state->mixed_domain == 1) {
491 flags |= DS_ROLE_PRIMARY_DS_MIXED_MODE;
494 domain = state->domain_name;
495 dns_domain = state->domain_dns;
496 forest = state->forest_dns;
498 domain_guid = state->domain_guid;
499 flags |= DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT;
503 info->basic.role = role;
504 info->basic.flags = flags;
505 info->basic.domain = domain;
506 info->basic.dns_domain = dns_domain;
507 info->basic.forest = forest;
508 info->basic.domain_guid = domain_guid;
513 case DS_ROLE_UPGRADE_STATUS:
515 info->upgrade.upgrading = DS_ROLE_NOT_UPGRADING;
516 info->upgrade.previous_role = DS_ROLE_PREVIOUS_UNKNOWN;
521 case DS_ROLE_OP_STATUS:
523 info->opstatus.status = DS_ROLE_OP_IDLE;
529 return WERR_INVALID_PARAM;
532 return WERR_INVALID_PARAM;
538 static NTSTATUS dcesrv_lsa_OpenPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
539 struct lsa_OpenPolicy2 *r)
542 struct lsa_policy_state *state;
543 struct dcesrv_handle *handle;
545 ZERO_STRUCTP(r->out.handle);
547 status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
548 if (!NT_STATUS_IS_OK(status)) {
552 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_POLICY);
554 return NT_STATUS_NO_MEMORY;
557 handle->data = talloc_steal(handle, state);
559 state->access_mask = r->in.access_mask;
560 state->handle = handle;
561 *r->out.handle = handle->wire_handle;
563 /* note that we have completely ignored the attr element of
564 the OpenPolicy. As far as I can tell, this is what w2k3
572 a wrapper around lsa_OpenPolicy2
574 static NTSTATUS dcesrv_lsa_OpenPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
575 struct lsa_OpenPolicy *r)
577 struct lsa_OpenPolicy2 r2;
579 r2.in.system_name = NULL;
580 r2.in.attr = r->in.attr;
581 r2.in.access_mask = r->in.access_mask;
582 r2.out.handle = r->out.handle;
584 return dcesrv_lsa_OpenPolicy2(dce_call, mem_ctx, &r2);
591 fill in the AccountDomain info
593 static NTSTATUS dcesrv_lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
594 struct lsa_DomainInfo *info)
596 info->name.string = state->domain_name;
597 info->sid = state->domain_sid;
603 fill in the DNS domain info
605 static NTSTATUS dcesrv_lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
606 struct lsa_DnsDomainInfo *info)
608 info->name.string = state->domain_name;
609 info->sid = state->domain_sid;
610 info->dns_domain.string = state->domain_dns;
611 info->dns_forest.string = state->forest_dns;
612 info->domain_guid = state->domain_guid;
620 static NTSTATUS dcesrv_lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
621 struct lsa_QueryInfoPolicy2 *r)
623 struct lsa_policy_state *state;
624 struct dcesrv_handle *h;
628 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
632 r->out.info = talloc(mem_ctx, union lsa_PolicyInformation);
634 return NT_STATUS_NO_MEMORY;
637 ZERO_STRUCTP(r->out.info);
639 switch (r->in.level) {
640 case LSA_POLICY_INFO_DOMAIN:
641 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
642 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &r->out.info->account_domain);
644 case LSA_POLICY_INFO_DNS:
645 return dcesrv_lsa_info_DNS(state, mem_ctx, &r->out.info->dns);
648 return NT_STATUS_INVALID_INFO_CLASS;
654 static NTSTATUS dcesrv_lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
655 struct lsa_QueryInfoPolicy *r)
657 struct lsa_QueryInfoPolicy2 r2;
660 r2.in.handle = r->in.handle;
661 r2.in.level = r->in.level;
663 status = dcesrv_lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
665 r->out.info = r2.out.info;
673 static NTSTATUS dcesrv_lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
674 struct lsa_SetInfoPolicy *r)
676 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
683 static NTSTATUS dcesrv_lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
684 struct lsa_ClearAuditLog *r)
686 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
693 static NTSTATUS dcesrv_lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
694 struct lsa_CreateAccount *r)
696 struct lsa_account_state *astate;
698 struct lsa_policy_state *state;
699 struct dcesrv_handle *h, *ah;
701 ZERO_STRUCTP(r->out.acct_handle);
703 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
707 astate = talloc(dce_call->conn, struct lsa_account_state);
708 if (astate == NULL) {
709 return NT_STATUS_NO_MEMORY;
712 astate->account_sid = dom_sid_dup(astate, r->in.sid);
713 if (astate->account_sid == NULL) {
715 return NT_STATUS_NO_MEMORY;
718 astate->policy = talloc_reference(astate, state);
719 astate->access_mask = r->in.access_mask;
721 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
724 return NT_STATUS_NO_MEMORY;
727 ah->data = talloc_steal(ah, astate);
729 *r->out.acct_handle = ah->wire_handle;
738 static NTSTATUS dcesrv_lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
739 struct lsa_EnumAccounts *r)
741 struct dcesrv_handle *h;
742 struct lsa_policy_state *state;
744 struct ldb_message **res;
745 const char * const attrs[] = { "objectSid", NULL};
748 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
752 /* NOTE: This call must only return accounts that have at least
755 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
756 "(&(objectSid=*)(privilege=*))");
758 return NT_STATUS_NO_SUCH_USER;
761 if (*r->in.resume_handle >= ret) {
762 return NT_STATUS_NO_MORE_ENTRIES;
765 count = ret - *r->in.resume_handle;
766 if (count > r->in.num_entries) {
767 count = r->in.num_entries;
771 return NT_STATUS_NO_MORE_ENTRIES;
774 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, count);
775 if (r->out.sids->sids == NULL) {
776 return NT_STATUS_NO_MEMORY;
779 for (i=0;i<count;i++) {
780 r->out.sids->sids[i].sid =
781 samdb_result_dom_sid(r->out.sids->sids,
782 res[i + *r->in.resume_handle],
784 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
787 r->out.sids->num_sids = count;
788 *r->out.resume_handle = count + *r->in.resume_handle;
796 lsa_CreateTrustedDomainEx2
798 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
800 struct lsa_CreateTrustedDomainEx2 *r)
802 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
806 lsa_CreateTrustedDomainEx
808 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
810 struct lsa_CreateTrustedDomainEx *r)
812 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
816 lsa_CreateTrustedDomain
818 static NTSTATUS dcesrv_lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
819 struct lsa_CreateTrustedDomain *r)
821 struct dcesrv_handle *policy_handle;
822 struct lsa_policy_state *policy_state;
823 struct lsa_trusted_domain_state *trusted_domain_state;
824 struct dcesrv_handle *handle;
825 struct ldb_message **msgs, *msg;
826 const char *attrs[] = {
832 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
833 ZERO_STRUCTP(r->out.trustdom_handle);
835 policy_state = policy_handle->data;
837 if (!r->in.info->name.string) {
838 return NT_STATUS_INVALID_PARAMETER;
840 name = r->in.info->name.string;
842 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
843 if (!trusted_domain_state) {
844 return NT_STATUS_NO_MEMORY;
846 trusted_domain_state->policy = policy_state;
848 msg = ldb_msg_new(mem_ctx);
850 return NT_STATUS_NO_MEMORY;
853 /* search for the trusted_domain record */
854 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
855 mem_ctx, policy_state->system_dn, &msgs, attrs,
856 "(&(cn=%s)(objectclass=trustedDomain))",
857 ldb_binary_encode_string(mem_ctx, r->in.info->name.string));
859 return NT_STATUS_OBJECT_NAME_COLLISION;
862 if (ret < 0 || ret > 1) {
863 DEBUG(0,("Found %d records matching DN %s\n", ret,
864 ldb_dn_get_linearized(policy_state->system_dn)));
865 return NT_STATUS_INTERNAL_DB_CORRUPTION;
868 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
869 if ( ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name)) {
870 return NT_STATUS_NO_MEMORY;
873 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "flatname", name);
875 if (r->in.info->sid) {
876 const char *sid_string = dom_sid_string(mem_ctx, r->in.info->sid);
878 return NT_STATUS_NO_MEMORY;
881 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "securityIdentifier", sid_string);
884 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "objectClass", "trustedDomain");
886 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
888 /* create the trusted_domain */
889 ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg);
890 if (ret != LDB_SUCCESS) {
891 DEBUG(0,("Failed to create trusted_domain record %s: %s\n",
892 ldb_dn_get_linearized(msg->dn), ldb_errstring(trusted_domain_state->policy->sam_ldb)));
893 return NT_STATUS_INTERNAL_DB_CORRUPTION;
896 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
898 return NT_STATUS_NO_MEMORY;
901 handle->data = talloc_steal(handle, trusted_domain_state);
903 trusted_domain_state->access_mask = r->in.access_mask;
904 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
906 *r->out.trustdom_handle = handle->wire_handle;
912 lsa_OpenTrustedDomain
914 static NTSTATUS dcesrv_lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
915 struct lsa_OpenTrustedDomain *r)
917 struct dcesrv_handle *policy_handle;
919 struct lsa_policy_state *policy_state;
920 struct lsa_trusted_domain_state *trusted_domain_state;
921 struct dcesrv_handle *handle;
922 struct ldb_message **msgs;
923 const char *attrs[] = {
927 const char *sid_string;
930 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
931 ZERO_STRUCTP(r->out.trustdom_handle);
932 policy_state = policy_handle->data;
934 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
935 if (!trusted_domain_state) {
936 return NT_STATUS_NO_MEMORY;
938 trusted_domain_state->policy = policy_state;
940 sid_string = dom_sid_string(mem_ctx, r->in.sid);
942 return NT_STATUS_NO_MEMORY;
945 /* search for the trusted_domain record */
946 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
947 mem_ctx, policy_state->system_dn, &msgs, attrs,
948 "(&(securityIdentifier=%s)(objectclass=trustedDomain))",
951 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
955 DEBUG(0,("Found %d records matching DN %s\n", ret,
956 ldb_dn_get_linearized(policy_state->system_dn)));
957 return NT_STATUS_INTERNAL_DB_CORRUPTION;
960 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
962 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
964 return NT_STATUS_NO_MEMORY;
967 handle->data = talloc_steal(handle, trusted_domain_state);
969 trusted_domain_state->access_mask = r->in.access_mask;
970 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
972 *r->out.trustdom_handle = handle->wire_handle;
979 lsa_OpenTrustedDomainByName
981 static NTSTATUS dcesrv_lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
983 struct lsa_OpenTrustedDomainByName *r)
985 struct dcesrv_handle *policy_handle;
987 struct lsa_policy_state *policy_state;
988 struct lsa_trusted_domain_state *trusted_domain_state;
989 struct dcesrv_handle *handle;
990 struct ldb_message **msgs;
991 const char *attrs[] = {
997 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
998 ZERO_STRUCTP(r->out.trustdom_handle);
999 policy_state = policy_handle->data;
1001 if (!r->in.name.string) {
1002 return NT_STATUS_INVALID_PARAMETER;
1005 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
1006 if (!trusted_domain_state) {
1007 return NT_STATUS_NO_MEMORY;
1009 trusted_domain_state->policy = policy_state;
1011 /* search for the trusted_domain record */
1012 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1013 mem_ctx, policy_state->system_dn, &msgs, attrs,
1014 "(&(flatname=%s)(objectclass=trustedDomain))",
1015 ldb_binary_encode_string(mem_ctx, r->in.name.string));
1017 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1021 DEBUG(0,("Found %d records matching DN %s\n", ret,
1022 ldb_dn_get_linearized(policy_state->system_dn)));
1023 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1026 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
1028 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1030 return NT_STATUS_NO_MEMORY;
1033 handle->data = talloc_steal(handle, trusted_domain_state);
1035 trusted_domain_state->access_mask = r->in.access_mask;
1036 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1038 *r->out.trustdom_handle = handle->wire_handle;
1040 return NT_STATUS_OK;
1046 lsa_SetTrustedDomainInfo
1048 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1049 struct lsa_SetTrustedDomainInfo *r)
1051 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1057 lsa_SetInfomrationTrustedDomain
1059 static NTSTATUS dcesrv_lsa_SetInformationTrustedDomain(struct dcesrv_call_state *dce_call,
1060 TALLOC_CTX *mem_ctx,
1061 struct lsa_SetInformationTrustedDomain *r)
1063 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1068 lsa_DeleteTrustedDomain
1070 static NTSTATUS dcesrv_lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1071 struct lsa_DeleteTrustedDomain *r)
1074 struct lsa_OpenTrustedDomain open;
1075 struct lsa_Delete delete;
1076 struct dcesrv_handle *h;
1078 open.in.handle = r->in.handle;
1079 open.in.sid = r->in.dom_sid;
1080 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1081 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1082 if (!open.out.trustdom_handle) {
1083 return NT_STATUS_NO_MEMORY;
1085 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
1086 if (!NT_STATUS_IS_OK(status)) {
1090 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1091 talloc_steal(mem_ctx, h);
1093 delete.in.handle = open.out.trustdom_handle;
1094 status = dcesrv_lsa_Delete(dce_call, mem_ctx, &delete);
1095 if (!NT_STATUS_IS_OK(status)) {
1098 return NT_STATUS_OK;
1101 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx,
1102 struct ldb_message *msg,
1103 struct lsa_TrustDomainInfoInfoEx *info_ex)
1105 info_ex->domain_name.string
1106 = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
1107 info_ex->netbios_name.string
1108 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1110 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1111 info_ex->trust_direction
1112 = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
1114 = ldb_msg_find_attr_as_int(msg, "trustType", 0);
1115 info_ex->trust_attributes
1116 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);
1117 return NT_STATUS_OK;
1121 lsa_QueryTrustedDomainInfo
1123 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1124 struct lsa_QueryTrustedDomainInfo *r)
1126 struct dcesrv_handle *h;
1127 struct lsa_trusted_domain_state *trusted_domain_state;
1128 struct ldb_message *msg;
1130 struct ldb_message **res;
1131 const char *attrs[] = {
1134 "securityIdentifier",
1141 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
1143 trusted_domain_state = h->data;
1145 /* pull all the user attributes */
1146 ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
1147 trusted_domain_state->trusted_domain_dn, &res, attrs);
1149 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1153 r->out.info = talloc(mem_ctx, union lsa_TrustedDomainInfo);
1155 return NT_STATUS_NO_MEMORY;
1157 switch (r->in.level) {
1158 case LSA_TRUSTED_DOMAIN_INFO_NAME:
1159 r->out.info->name.netbios_name.string
1160 = samdb_result_string(msg, "flatname", NULL);
1162 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1163 r->out.info->posix_offset.posix_offset
1164 = samdb_result_uint(msg, "posixOffset", 0);
1166 #if 0 /* Win2k3 doesn't implement this */
1167 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
1168 r->out.info->info_basic.netbios_name.string
1169 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1170 r->out.info->info_basic.sid
1171 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1174 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1175 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->info_ex);
1177 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1178 ZERO_STRUCT(r->out.info->full_info);
1179 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->full_info.info_ex);
1181 case LSA_TRUSTED_DOMAIN_INFO_INFO_ALL:
1182 ZERO_STRUCT(r->out.info->info_all);
1183 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->info_all.info_ex);
1185 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS_INFO:
1186 case LSA_TRUSTED_DOMAIN_INFO_11:
1187 /* oops, we don't want to return the info after all */
1188 talloc_free(r->out.info);
1190 return NT_STATUS_INVALID_PARAMETER;
1192 /* oops, we don't want to return the info after all */
1193 talloc_free(r->out.info);
1195 return NT_STATUS_INVALID_INFO_CLASS;
1198 return NT_STATUS_OK;
1203 lsa_QueryTrustedDomainInfoBySid
1205 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1206 struct lsa_QueryTrustedDomainInfoBySid *r)
1209 struct lsa_OpenTrustedDomain open;
1210 struct lsa_QueryTrustedDomainInfo query;
1211 struct dcesrv_handle *h;
1212 open.in.handle = r->in.handle;
1213 open.in.sid = r->in.dom_sid;
1214 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1215 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1216 if (!open.out.trustdom_handle) {
1217 return NT_STATUS_NO_MEMORY;
1219 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
1220 if (!NT_STATUS_IS_OK(status)) {
1224 /* Ensure this handle goes away at the end of this call */
1225 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1226 talloc_steal(mem_ctx, h);
1228 query.in.trustdom_handle = open.out.trustdom_handle;
1229 query.in.level = r->in.level;
1230 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1231 if (!NT_STATUS_IS_OK(status)) {
1235 r->out.info = query.out.info;
1236 return NT_STATUS_OK;
1240 lsa_SetTrustedDomainInfoByName
1242 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1243 TALLOC_CTX *mem_ctx,
1244 struct lsa_SetTrustedDomainInfoByName *r)
1246 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1250 lsa_QueryTrustedDomainInfoByName
1252 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1253 TALLOC_CTX *mem_ctx,
1254 struct lsa_QueryTrustedDomainInfoByName *r)
1257 struct lsa_OpenTrustedDomainByName open;
1258 struct lsa_QueryTrustedDomainInfo query;
1259 struct dcesrv_handle *h;
1260 open.in.handle = r->in.handle;
1261 open.in.name = r->in.trusted_domain;
1262 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1263 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1264 if (!open.out.trustdom_handle) {
1265 return NT_STATUS_NO_MEMORY;
1267 status = dcesrv_lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &open);
1268 if (!NT_STATUS_IS_OK(status)) {
1272 /* Ensure this handle goes away at the end of this call */
1273 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1274 talloc_steal(mem_ctx, h);
1276 query.in.trustdom_handle = open.out.trustdom_handle;
1277 query.in.level = r->in.level;
1278 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1279 if (!NT_STATUS_IS_OK(status)) {
1283 r->out.info = query.out.info;
1284 return NT_STATUS_OK;
1288 lsa_CloseTrustedDomainEx
1290 static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
1291 TALLOC_CTX *mem_ctx,
1292 struct lsa_CloseTrustedDomainEx *r)
1294 /* The result of a bad hair day from an IDL programmer? Not
1295 * implmented in Win2k3. You should always just lsa_Close
1297 return NT_STATUS_NOT_IMPLEMENTED;
1302 comparison function for sorting lsa_DomainInformation array
1304 static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
1306 return strcasecmp_m(e1->name.string, e2->name.string);
1312 static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1313 struct lsa_EnumTrustDom *r)
1315 struct dcesrv_handle *policy_handle;
1316 struct lsa_DomainInfo *entries;
1317 struct lsa_policy_state *policy_state;
1318 struct ldb_message **domains;
1319 const char *attrs[] = {
1321 "securityIdentifier",
1328 *r->out.resume_handle = 0;
1330 r->out.domains->domains = NULL;
1331 r->out.domains->count = 0;
1333 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1335 policy_state = policy_handle->data;
1337 /* search for all users in this domain. This could possibly be cached and
1338 resumed based on resume_key */
1339 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1340 "objectclass=trustedDomain");
1342 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1344 if (count == 0 || r->in.max_size == 0) {
1345 return NT_STATUS_OK;
1348 /* convert to lsa_TrustInformation format */
1349 entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
1351 return NT_STATUS_NO_MEMORY;
1353 for (i=0;i<count;i++) {
1354 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
1355 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
1358 /* sort the results by name */
1359 qsort(entries, count, sizeof(*entries),
1360 (comparison_fn_t)compare_DomainInfo);
1362 if (*r->in.resume_handle >= count) {
1363 *r->out.resume_handle = -1;
1365 return NT_STATUS_NO_MORE_ENTRIES;
1368 /* return the rest, limit by max_size. Note that we
1369 use the w2k3 element size value of 60 */
1370 r->out.domains->count = count - *r->in.resume_handle;
1371 r->out.domains->count = MIN(r->out.domains->count,
1372 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
1374 r->out.domains->domains = entries + *r->in.resume_handle;
1375 r->out.domains->count = r->out.domains->count;
1377 if (r->out.domains->count < count - *r->in.resume_handle) {
1378 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1379 return STATUS_MORE_ENTRIES;
1382 return NT_STATUS_OK;
1386 comparison function for sorting lsa_DomainInformation array
1388 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
1390 return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
1394 lsa_EnumTrustedDomainsEx
1396 static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1397 struct lsa_EnumTrustedDomainsEx *r)
1399 struct dcesrv_handle *policy_handle;
1400 struct lsa_TrustDomainInfoInfoEx *entries;
1401 struct lsa_policy_state *policy_state;
1402 struct ldb_message **domains;
1403 const char *attrs[] = {
1406 "securityIdentifier",
1416 *r->out.resume_handle = 0;
1418 r->out.domains->domains = NULL;
1419 r->out.domains->count = 0;
1421 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1423 policy_state = policy_handle->data;
1425 /* search for all users in this domain. This could possibly be cached and
1426 resumed based on resume_key */
1427 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1428 "objectclass=trustedDomain");
1430 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1432 if (count == 0 || r->in.max_size == 0) {
1433 return NT_STATUS_OK;
1436 /* convert to lsa_DomainInformation format */
1437 entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
1439 return NT_STATUS_NO_MEMORY;
1441 for (i=0;i<count;i++) {
1442 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
1443 if (!NT_STATUS_IS_OK(nt_status)) {
1448 /* sort the results by name */
1449 qsort(entries, count, sizeof(*entries),
1450 (comparison_fn_t)compare_TrustDomainInfoInfoEx);
1452 if (*r->in.resume_handle >= count) {
1453 *r->out.resume_handle = -1;
1455 return NT_STATUS_NO_MORE_ENTRIES;
1458 /* return the rest, limit by max_size. Note that we
1459 use the w2k3 element size value of 60 */
1460 r->out.domains->count = count - *r->in.resume_handle;
1461 r->out.domains->count = MIN(r->out.domains->count,
1462 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
1464 r->out.domains->domains = entries + *r->in.resume_handle;
1465 r->out.domains->count = r->out.domains->count;
1467 if (r->out.domains->count < count - *r->in.resume_handle) {
1468 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1469 return STATUS_MORE_ENTRIES;
1472 return NT_STATUS_OK;
1477 return the authority name and authority sid, given a sid
1479 static NTSTATUS dcesrv_lsa_authority_name(struct lsa_policy_state *state,
1480 TALLOC_CTX *mem_ctx, struct dom_sid *sid,
1481 const char **authority_name,
1482 struct dom_sid **authority_sid)
1484 if (dom_sid_in_domain(state->domain_sid, sid)) {
1485 *authority_name = state->domain_name;
1486 *authority_sid = state->domain_sid;
1487 return NT_STATUS_OK;
1490 if (dom_sid_in_domain(state->builtin_sid, sid)) {
1491 *authority_name = "BUILTIN";
1492 *authority_sid = state->builtin_sid;
1493 return NT_STATUS_OK;
1496 *authority_sid = dom_sid_dup(mem_ctx, sid);
1497 if (*authority_sid == NULL) {
1498 return NT_STATUS_NO_MEMORY;
1500 (*authority_sid)->num_auths = 0;
1501 *authority_name = dom_sid_string(mem_ctx, *authority_sid);
1502 if (*authority_name == NULL) {
1503 return NT_STATUS_NO_MEMORY;
1506 return NT_STATUS_OK;
1510 add to the lsa_RefDomainList for LookupSids and LookupNames
1512 static NTSTATUS dcesrv_lsa_authority_list(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
1513 struct dom_sid *sid,
1514 struct lsa_RefDomainList *domains,
1515 uint32_t *sid_index)
1518 const char *authority_name;
1519 struct dom_sid *authority_sid;
1522 /* work out the authority name */
1523 status = dcesrv_lsa_authority_name(state, mem_ctx, sid,
1524 &authority_name, &authority_sid);
1525 if (!NT_STATUS_IS_OK(status)) {
1529 /* see if we've already done this authority name */
1530 for (i=0;i<domains->count;i++) {
1531 if (strcmp(authority_name, domains->domains[i].name.string) == 0) {
1533 return NT_STATUS_OK;
1537 domains->domains = talloc_realloc(domains,
1539 struct lsa_DomainInfo,
1541 if (domains->domains == NULL) {
1542 return NT_STATUS_NO_MEMORY;
1544 domains->domains[i].name.string = authority_name;
1545 domains->domains[i].sid = authority_sid;
1547 domains->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER * domains->count;
1550 return NT_STATUS_OK;
1554 lookup a name for 1 SID
1556 static NTSTATUS dcesrv_lsa_lookup_sid(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
1557 struct dom_sid *sid, const char *sid_str,
1558 const char **name, uint32_t *atype)
1561 struct ldb_message **res;
1562 const char * const attrs[] = { "sAMAccountName", "sAMAccountType", "name", NULL};
1565 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
1566 "objectSid=%s", ldap_encode_ndr_dom_sid(mem_ctx, sid));
1568 *name = ldb_msg_find_attr_as_string(res[0], "sAMAccountName", NULL);
1570 *name = ldb_msg_find_attr_as_string(res[0], "name", NULL);
1572 *name = talloc_strdup(mem_ctx, sid_str);
1573 NT_STATUS_HAVE_NO_MEMORY(*name);
1577 *atype = samdb_result_uint(res[0], "sAMAccountType", 0);
1579 return NT_STATUS_OK;
1582 status = sidmap_allocated_sid_lookup(state->sidmap, mem_ctx, sid, name, atype);
1591 static NTSTATUS dcesrv_lsa_LookupSids2(struct dcesrv_call_state *dce_call,
1592 TALLOC_CTX *mem_ctx,
1593 struct lsa_LookupSids2 *r)
1595 struct lsa_policy_state *state;
1597 NTSTATUS status = NT_STATUS_OK;
1599 r->out.domains = NULL;
1601 status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
1602 if (!NT_STATUS_IS_OK(status)) {
1606 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
1607 if (r->out.domains == NULL) {
1608 return NT_STATUS_NO_MEMORY;
1611 r->out.names = talloc_zero(mem_ctx, struct lsa_TransNameArray2);
1612 if (r->out.names == NULL) {
1613 return NT_STATUS_NO_MEMORY;
1618 r->out.names->names = talloc_array(r->out.names, struct lsa_TranslatedName2,
1619 r->in.sids->num_sids);
1620 if (r->out.names->names == NULL) {
1621 return NT_STATUS_NO_MEMORY;
1624 for (i=0;i<r->in.sids->num_sids;i++) {
1625 struct dom_sid *sid = r->in.sids->sids[i].sid;
1626 char *sid_str = dom_sid_string(mem_ctx, sid);
1628 uint32_t atype, rtype, sid_index;
1631 r->out.names->count++;
1634 r->out.names->names[i].sid_type = SID_NAME_UNKNOWN;
1635 r->out.names->names[i].name.string = sid_str;
1636 r->out.names->names[i].sid_index = 0xFFFFFFFF;
1637 r->out.names->names[i].unknown = 0;
1639 if (sid_str == NULL) {
1640 r->out.names->names[i].name.string = "(SIDERROR)";
1641 status = STATUS_SOME_UNMAPPED;
1645 /* work out the authority name */
1646 status2 = dcesrv_lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
1647 if (!NT_STATUS_IS_OK(status2)) {
1651 status2 = dcesrv_lsa_lookup_sid(state, mem_ctx, sid, sid_str,
1653 if (!NT_STATUS_IS_OK(status2)) {
1654 status = STATUS_SOME_UNMAPPED;
1658 rtype = samdb_atype_map(atype);
1659 if (rtype == SID_NAME_UNKNOWN) {
1660 status = STATUS_SOME_UNMAPPED;
1664 r->out.names->names[i].sid_type = rtype;
1665 r->out.names->names[i].name.string = name;
1666 r->out.names->names[i].sid_index = sid_index;
1667 r->out.names->names[i].unknown = 0;
1677 Identical to LookupSids2, but doesn't take a policy handle
1680 static NTSTATUS dcesrv_lsa_LookupSids3(struct dcesrv_call_state *dce_call,
1681 TALLOC_CTX *mem_ctx,
1682 struct lsa_LookupSids3 *r)
1684 struct lsa_LookupSids2 r2;
1685 struct lsa_OpenPolicy2 pol;
1687 struct dcesrv_handle *h;
1689 /* No policy handle on the wire, so make one up here */
1690 r2.in.handle = talloc(mem_ctx, struct policy_handle);
1691 if (!r2.in.handle) {
1692 return NT_STATUS_NO_MEMORY;
1695 pol.out.handle = r2.in.handle;
1696 pol.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1698 pol.in.system_name = NULL;
1699 status = dcesrv_lsa_OpenPolicy2(dce_call, mem_ctx, &pol);
1700 if (!NT_STATUS_IS_OK(status)) {
1704 /* ensure this handle goes away at the end of this call */
1705 DCESRV_PULL_HANDLE(h, r2.in.handle, LSA_HANDLE_POLICY);
1706 talloc_steal(mem_ctx, h);
1708 r2.in.sids = r->in.sids;
1709 r2.in.names = r->in.names;
1710 r2.in.level = r->in.level;
1711 r2.in.count = r->in.count;
1712 r2.in.unknown1 = r->in.unknown1;
1713 r2.in.unknown2 = r->in.unknown2;
1714 r2.out.count = r->out.count;
1715 r2.out.names = r->out.names;
1717 status = dcesrv_lsa_LookupSids2(dce_call, mem_ctx, &r2);
1718 if (dce_call->fault_code != 0) {
1722 r->out.domains = r2.out.domains;
1723 r->out.names = r2.out.names;
1724 r->out.count = r2.out.count;
1733 static NTSTATUS dcesrv_lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1734 struct lsa_LookupSids *r)
1736 struct lsa_LookupSids2 r2;
1740 r2.in.handle = r->in.handle;
1741 r2.in.sids = r->in.sids;
1743 r2.in.level = r->in.level;
1744 r2.in.count = r->in.count;
1747 r2.out.count = r->out.count;
1748 r2.out.names = NULL;
1750 status = dcesrv_lsa_LookupSids2(dce_call, mem_ctx, &r2);
1751 if (dce_call->fault_code != 0) {
1755 r->out.domains = r2.out.domains;
1756 if (!r2.out.names) {
1757 r->out.names = NULL;
1761 r->out.names = talloc(mem_ctx, struct lsa_TransNameArray);
1762 if (r->out.names == NULL) {
1763 return NT_STATUS_NO_MEMORY;
1765 r->out.names->count = r2.out.names->count;
1766 r->out.names->names = talloc_array(r->out.names, struct lsa_TranslatedName,
1767 r->out.names->count);
1768 if (r->out.names->names == NULL) {
1769 return NT_STATUS_NO_MEMORY;
1771 for (i=0;i<r->out.names->count;i++) {
1772 r->out.names->names[i].sid_type = r2.out.names->names[i].sid_type;
1773 r->out.names->names[i].name.string = r2.out.names->names[i].name.string;
1774 r->out.names->names[i].sid_index = r2.out.names->names[i].sid_index;
1784 static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1785 struct lsa_OpenAccount *r)
1787 struct dcesrv_handle *h, *ah;
1788 struct lsa_policy_state *state;
1789 struct lsa_account_state *astate;
1791 ZERO_STRUCTP(r->out.acct_handle);
1793 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1797 astate = talloc(dce_call->conn, struct lsa_account_state);
1798 if (astate == NULL) {
1799 return NT_STATUS_NO_MEMORY;
1802 astate->account_sid = dom_sid_dup(astate, r->in.sid);
1803 if (astate->account_sid == NULL) {
1804 talloc_free(astate);
1805 return NT_STATUS_NO_MEMORY;
1808 astate->policy = talloc_reference(astate, state);
1809 astate->access_mask = r->in.access_mask;
1811 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
1813 talloc_free(astate);
1814 return NT_STATUS_NO_MEMORY;
1817 ah->data = talloc_steal(ah, astate);
1819 *r->out.acct_handle = ah->wire_handle;
1821 return NT_STATUS_OK;
1826 lsa_EnumPrivsAccount
1828 static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
1829 TALLOC_CTX *mem_ctx,
1830 struct lsa_EnumPrivsAccount *r)
1832 struct dcesrv_handle *h;
1833 struct lsa_account_state *astate;
1835 struct ldb_message **res;
1836 const char * const attrs[] = { "privilege", NULL};
1837 struct ldb_message_element *el;
1840 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1844 r->out.privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
1845 r->out.privs->count = 0;
1846 r->out.privs->unknown = 0;
1847 r->out.privs->set = NULL;
1849 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
1850 if (sidstr == NULL) {
1851 return NT_STATUS_NO_MEMORY;
1854 ret = gendb_search(astate->policy->sam_ldb, mem_ctx, NULL, &res, attrs,
1855 "objectSid=%s", sidstr);
1857 return NT_STATUS_OK;
1860 el = ldb_msg_find_element(res[0], "privilege");
1861 if (el == NULL || el->num_values == 0) {
1862 return NT_STATUS_OK;
1865 r->out.privs->set = talloc_array(r->out.privs,
1866 struct lsa_LUIDAttribute, el->num_values);
1867 if (r->out.privs->set == NULL) {
1868 return NT_STATUS_NO_MEMORY;
1871 for (i=0;i<el->num_values;i++) {
1872 int id = sec_privilege_id((const char *)el->values[i].data);
1874 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1876 r->out.privs->set[i].attribute = 0;
1877 r->out.privs->set[i].luid.low = id;
1878 r->out.privs->set[i].luid.high = 0;
1881 r->out.privs->count = el->num_values;
1883 return NT_STATUS_OK;
1887 lsa_EnumAccountRights
1889 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
1890 TALLOC_CTX *mem_ctx,
1891 struct lsa_EnumAccountRights *r)
1893 struct dcesrv_handle *h;
1894 struct lsa_policy_state *state;
1896 struct ldb_message **res;
1897 const char * const attrs[] = { "privilege", NULL};
1899 struct ldb_message_element *el;
1901 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1905 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
1906 if (sidstr == NULL) {
1907 return NT_STATUS_NO_MEMORY;
1910 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
1911 "(&(objectSid=%s)(privilege=*))", sidstr);
1913 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1916 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1919 DEBUG(3, ("searching for account rights for SID: %s failed: %s",
1920 dom_sid_string(mem_ctx, r->in.sid),
1921 ldb_errstring(state->sam_ldb)));
1922 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1925 el = ldb_msg_find_element(res[0], "privilege");
1926 if (el == NULL || el->num_values == 0) {
1927 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1930 r->out.rights->count = el->num_values;
1931 r->out.rights->names = talloc_array(r->out.rights,
1932 struct lsa_StringLarge, r->out.rights->count);
1933 if (r->out.rights->names == NULL) {
1934 return NT_STATUS_NO_MEMORY;
1937 for (i=0;i<el->num_values;i++) {
1938 r->out.rights->names[i].string = (const char *)el->values[i].data;
1941 return NT_STATUS_OK;
1947 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
1949 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
1950 TALLOC_CTX *mem_ctx,
1951 struct lsa_policy_state *state,
1953 struct dom_sid *sid,
1954 const struct lsa_RightSet *rights)
1957 struct ldb_message *msg;
1958 struct ldb_message_element *el;
1960 struct lsa_EnumAccountRights r2;
1962 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, sid);
1963 if (sidstr == NULL) {
1964 return NT_STATUS_NO_MEMORY;
1967 msg = ldb_msg_new(mem_ctx);
1969 return NT_STATUS_NO_MEMORY;
1972 msg->dn = samdb_search_dn(state->sam_ldb, mem_ctx,
1973 NULL, "objectSid=%s", sidstr);
1974 if (msg->dn == NULL) {
1976 if (ldb_flag == LDB_FLAG_MOD_DELETE) {
1977 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1979 status = samdb_create_foreign_security_principal(state->sam_ldb, mem_ctx,
1981 if (!NT_STATUS_IS_OK(status)) {
1984 return NT_STATUS_NO_SUCH_USER;
1987 if (ldb_msg_add_empty(msg, "privilege", ldb_flag, NULL)) {
1988 return NT_STATUS_NO_MEMORY;
1991 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1994 r2.in.handle = &state->handle->wire_handle;
1996 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
1998 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1999 if (!NT_STATUS_IS_OK(status)) {
2000 ZERO_STRUCTP(r2.out.rights);
2004 for (i=0;i<rights->count;i++) {
2005 if (sec_privilege_id(rights->names[i].string) == -1) {
2006 return NT_STATUS_NO_SUCH_PRIVILEGE;
2009 if (ldb_flag == LDB_FLAG_MOD_ADD) {
2011 for (j=0;j<r2.out.rights->count;j++) {
2012 if (strcasecmp_m(r2.out.rights->names[j].string,
2013 rights->names[i].string) == 0) {
2017 if (j != r2.out.rights->count) continue;
2020 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
2021 if (ret != LDB_SUCCESS) {
2022 return NT_STATUS_NO_MEMORY;
2026 el = ldb_msg_find_element(msg, "privilege");
2028 return NT_STATUS_OK;
2031 ret = samdb_modify(state->sam_ldb, mem_ctx, msg);
2033 if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
2034 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2036 DEBUG(3, ("Could not %s attributes from %s: %s",
2037 ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add",
2038 ldb_dn_get_linearized(msg->dn), ldb_errstring(state->sam_ldb)));
2039 return NT_STATUS_UNEXPECTED_IO_ERROR;
2042 return NT_STATUS_OK;
2046 lsa_AddPrivilegesToAccount
2048 static NTSTATUS dcesrv_lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2049 struct lsa_AddPrivilegesToAccount *r)
2051 struct lsa_RightSet rights;
2052 struct dcesrv_handle *h;
2053 struct lsa_account_state *astate;
2056 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2060 rights.count = r->in.privs->count;
2061 rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
2062 if (rights.names == NULL) {
2063 return NT_STATUS_NO_MEMORY;
2065 for (i=0;i<rights.count;i++) {
2066 int id = r->in.privs->set[i].luid.low;
2067 if (r->in.privs->set[i].luid.high) {
2068 return NT_STATUS_NO_SUCH_PRIVILEGE;
2070 rights.names[i].string = sec_privilege_name(id);
2071 if (rights.names[i].string == NULL) {
2072 return NT_STATUS_NO_SUCH_PRIVILEGE;
2076 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2077 LDB_FLAG_MOD_ADD, astate->account_sid,
2083 lsa_RemovePrivilegesFromAccount
2085 static NTSTATUS dcesrv_lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2086 struct lsa_RemovePrivilegesFromAccount *r)
2088 struct lsa_RightSet *rights;
2089 struct dcesrv_handle *h;
2090 struct lsa_account_state *astate;
2093 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2097 rights = talloc(mem_ctx, struct lsa_RightSet);
2099 if (r->in.remove_all == 1 &&
2100 r->in.privs == NULL) {
2101 struct lsa_EnumAccountRights r2;
2104 r2.in.handle = &astate->policy->handle->wire_handle;
2105 r2.in.sid = astate->account_sid;
2106 r2.out.rights = rights;
2108 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
2109 if (!NT_STATUS_IS_OK(status)) {
2113 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2114 LDB_FLAG_MOD_DELETE, astate->account_sid,
2118 if (r->in.remove_all != 0) {
2119 return NT_STATUS_INVALID_PARAMETER;
2122 rights->count = r->in.privs->count;
2123 rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
2124 if (rights->names == NULL) {
2125 return NT_STATUS_NO_MEMORY;
2127 for (i=0;i<rights->count;i++) {
2128 int id = r->in.privs->set[i].luid.low;
2129 if (r->in.privs->set[i].luid.high) {
2130 return NT_STATUS_NO_SUCH_PRIVILEGE;
2132 rights->names[i].string = sec_privilege_name(id);
2133 if (rights->names[i].string == NULL) {
2134 return NT_STATUS_NO_SUCH_PRIVILEGE;
2138 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2139 LDB_FLAG_MOD_DELETE, astate->account_sid,
2145 lsa_GetQuotasForAccount
2147 static NTSTATUS dcesrv_lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2148 struct lsa_GetQuotasForAccount *r)
2150 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2155 lsa_SetQuotasForAccount
2157 static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2158 struct lsa_SetQuotasForAccount *r)
2160 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2165 lsa_GetSystemAccessAccount
2167 static NTSTATUS dcesrv_lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2168 struct lsa_GetSystemAccessAccount *r)
2170 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2175 lsa_SetSystemAccessAccount
2177 static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2178 struct lsa_SetSystemAccessAccount *r)
2180 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2187 static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2188 struct lsa_CreateSecret *r)
2190 struct dcesrv_handle *policy_handle;
2191 struct lsa_policy_state *policy_state;
2192 struct lsa_secret_state *secret_state;
2193 struct dcesrv_handle *handle;
2194 struct ldb_message **msgs, *msg;
2196 const char *attrs[] = {
2204 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2205 ZERO_STRUCTP(r->out.sec_handle);
2207 policy_state = policy_handle->data;
2209 if (!r->in.name.string) {
2210 return NT_STATUS_INVALID_PARAMETER;
2213 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2214 if (!secret_state) {
2215 return NT_STATUS_NO_MEMORY;
2217 secret_state->policy = policy_state;
2219 msg = ldb_msg_new(mem_ctx);
2221 return NT_STATUS_NO_MEMORY;
2224 if (strncmp("G$", r->in.name.string, 2) == 0) {
2226 name = &r->in.name.string[2];
2227 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
2228 secret_state->global = True;
2230 if (strlen(name) < 1) {
2231 return NT_STATUS_INVALID_PARAMETER;
2234 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
2235 /* search for the secret record */
2236 ret = gendb_search(secret_state->sam_ldb,
2237 mem_ctx, policy_state->system_dn, &msgs, attrs,
2238 "(&(cn=%s)(objectclass=secret))",
2241 return NT_STATUS_OBJECT_NAME_COLLISION;
2245 DEBUG(0,("Failure searching for CN=%s: %s\n",
2246 name2, ldb_errstring(secret_state->sam_ldb)));
2247 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2250 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
2251 if (!name2 || ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
2252 return NT_STATUS_NO_MEMORY;
2255 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
2258 secret_state->global = False;
2260 name = r->in.name.string;
2261 if (strlen(name) < 1) {
2262 return NT_STATUS_INVALID_PARAMETER;
2265 secret_state->sam_ldb = talloc_reference(secret_state, secrets_db_connect(mem_ctx));
2266 /* search for the secret record */
2267 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2268 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2270 "(&(cn=%s)(objectclass=secret))",
2271 ldb_binary_encode_string(mem_ctx, name));
2273 return NT_STATUS_OBJECT_NAME_COLLISION;
2277 DEBUG(0,("Failure searching for CN=%s: %s\n",
2278 name, ldb_errstring(secret_state->sam_ldb)));
2279 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2282 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name);
2283 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
2286 /* pull in all the template attributes. Note this is always from the global samdb */
2287 ret = samdb_copy_template(secret_state->policy->sam_ldb, msg,
2288 "(&(cn=TemplateSecret)(objectclass=secretTemplate))", &errstr);
2290 DEBUG(0,("Failed to load TemplateSecret from samdb: %s\n",
2292 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2295 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
2297 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
2299 /* create the secret */
2300 ret = samdb_add(secret_state->sam_ldb, mem_ctx, msg);
2302 DEBUG(0,("Failed to create secret record %s: %s\n",
2303 ldb_dn_get_linearized(msg->dn),
2304 ldb_errstring(secret_state->sam_ldb)));
2305 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2308 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2310 return NT_STATUS_NO_MEMORY;
2313 handle->data = talloc_steal(handle, secret_state);
2315 secret_state->access_mask = r->in.access_mask;
2316 secret_state->policy = talloc_reference(secret_state, policy_state);
2318 *r->out.sec_handle = handle->wire_handle;
2320 return NT_STATUS_OK;
2327 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2328 struct lsa_OpenSecret *r)
2330 struct dcesrv_handle *policy_handle;
2332 struct lsa_policy_state *policy_state;
2333 struct lsa_secret_state *secret_state;
2334 struct dcesrv_handle *handle;
2335 struct ldb_message **msgs;
2336 const char *attrs[] = {
2344 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2345 ZERO_STRUCTP(r->out.sec_handle);
2346 policy_state = policy_handle->data;
2348 if (!r->in.name.string) {
2349 return NT_STATUS_INVALID_PARAMETER;
2352 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2353 if (!secret_state) {
2354 return NT_STATUS_NO_MEMORY;
2356 secret_state->policy = policy_state;
2358 if (strncmp("G$", r->in.name.string, 2) == 0) {
2359 name = &r->in.name.string[2];
2360 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
2361 secret_state->global = True;
2363 if (strlen(name) < 1) {
2364 return NT_STATUS_INVALID_PARAMETER;
2367 /* search for the secret record */
2368 ret = gendb_search(secret_state->sam_ldb,
2369 mem_ctx, policy_state->system_dn, &msgs, attrs,
2370 "(&(cn=%s Secret)(objectclass=secret))",
2371 ldb_binary_encode_string(mem_ctx, name));
2373 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2377 DEBUG(0,("Found %d records matching DN %s\n", ret,
2378 ldb_dn_get_linearized(policy_state->system_dn)));
2379 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2383 secret_state->sam_ldb = talloc_reference(secret_state, secrets_db_connect(mem_ctx));
2385 secret_state->global = False;
2386 name = r->in.name.string;
2387 if (strlen(name) < 1) {
2388 return NT_STATUS_INVALID_PARAMETER;
2391 /* search for the secret record */
2392 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2393 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2395 "(&(cn=%s)(objectclass=secret))",
2396 ldb_binary_encode_string(mem_ctx, name));
2398 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2402 DEBUG(0,("Found %d records matching DN %s\n", ret,
2403 ldb_dn_get_linearized(policy_state->system_dn)));
2404 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2408 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
2410 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2412 return NT_STATUS_NO_MEMORY;
2415 handle->data = talloc_steal(handle, secret_state);
2417 secret_state->access_mask = r->in.access_mask;
2418 secret_state->policy = talloc_reference(secret_state, policy_state);
2420 *r->out.sec_handle = handle->wire_handle;
2422 return NT_STATUS_OK;
2429 static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2430 struct lsa_SetSecret *r)
2433 struct dcesrv_handle *h;
2434 struct lsa_secret_state *secret_state;
2435 struct ldb_message *msg;
2436 DATA_BLOB session_key;
2437 DATA_BLOB crypt_secret, secret;
2440 NTSTATUS status = NT_STATUS_OK;
2442 struct timeval now = timeval_current();
2443 NTTIME nt_now = timeval_to_nttime(&now);
2445 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2447 secret_state = h->data;
2449 msg = ldb_msg_new(mem_ctx);
2451 return NT_STATUS_NO_MEMORY;
2454 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
2456 return NT_STATUS_NO_MEMORY;
2458 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2459 if (!NT_STATUS_IS_OK(status)) {
2463 if (r->in.old_val) {
2465 crypt_secret.data = r->in.old_val->data;
2466 crypt_secret.length = r->in.old_val->size;
2468 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2469 if (!NT_STATUS_IS_OK(status)) {
2473 val.data = secret.data;
2474 val.length = secret.length;
2477 if (samdb_msg_add_value(secret_state->sam_ldb,
2478 mem_ctx, msg, "priorValue", &val) != 0) {
2479 return NT_STATUS_NO_MEMORY;
2482 /* set old value mtime */
2483 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2484 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
2485 return NT_STATUS_NO_MEMORY;
2488 if (!r->in.new_val) {
2489 /* This behaviour varies depending of if this is a local, or a global secret... */
2490 if (secret_state->global) {
2491 /* set old value mtime */
2492 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2493 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2494 return NT_STATUS_NO_MEMORY;
2497 if (samdb_msg_add_delete(secret_state->sam_ldb,
2498 mem_ctx, msg, "currentValue")) {
2499 return NT_STATUS_NO_MEMORY;
2501 if (samdb_msg_add_delete(secret_state->sam_ldb,
2502 mem_ctx, msg, "lastSetTime")) {
2503 return NT_STATUS_NO_MEMORY;
2509 if (r->in.new_val) {
2511 crypt_secret.data = r->in.new_val->data;
2512 crypt_secret.length = r->in.new_val->size;
2514 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2515 if (!NT_STATUS_IS_OK(status)) {
2519 val.data = secret.data;
2520 val.length = secret.length;
2523 if (samdb_msg_add_value(secret_state->sam_ldb,
2524 mem_ctx, msg, "currentValue", &val) != 0) {
2525 return NT_STATUS_NO_MEMORY;
2528 /* set new value mtime */
2529 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2530 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2531 return NT_STATUS_NO_MEMORY;
2534 /* If the old value is not set, then migrate the
2535 * current value to the old value */
2536 if (!r->in.old_val) {
2537 const struct ldb_val *new_val;
2538 NTTIME last_set_time;
2539 struct ldb_message **res;
2540 const char *attrs[] = {
2546 /* search for the secret record */
2547 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
2548 secret_state->secret_dn, &res, attrs);
2550 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2554 DEBUG(0,("Found %d records matching dn=%s\n", ret,
2555 ldb_dn_get_linearized(secret_state->secret_dn)));
2556 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2559 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2560 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2564 if (samdb_msg_add_value(secret_state->sam_ldb,
2565 mem_ctx, msg, "priorValue",
2567 return NT_STATUS_NO_MEMORY;
2571 /* set new value mtime */
2572 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2573 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2574 mem_ctx, msg, "priorSetTime", last_set_time) != 0) {
2575 return NT_STATUS_NO_MEMORY;
2581 /* modify the samdb record */
2582 ret = samdb_replace(secret_state->sam_ldb, mem_ctx, msg);
2584 /* we really need samdb.c to return NTSTATUS */
2585 return NT_STATUS_UNSUCCESSFUL;
2588 return NT_STATUS_OK;
2595 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2596 struct lsa_QuerySecret *r)
2598 struct dcesrv_handle *h;
2599 struct lsa_secret_state *secret_state;
2600 struct ldb_message *msg;
2601 DATA_BLOB session_key;
2602 DATA_BLOB crypt_secret, secret;
2604 struct ldb_message **res;
2605 const char *attrs[] = {
2615 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2617 secret_state = h->data;
2619 /* pull all the user attributes */
2620 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2621 secret_state->secret_dn, &res, attrs);
2623 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2627 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2628 if (!NT_STATUS_IS_OK(nt_status)) {
2632 if (r->in.old_val) {
2633 const struct ldb_val *prior_val;
2634 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2635 if (!r->out.old_val) {
2636 return NT_STATUS_NO_MEMORY;
2638 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
2640 if (prior_val && prior_val->length) {
2641 secret.data = prior_val->data;
2642 secret.length = prior_val->length;
2645 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2646 if (!crypt_secret.length) {
2647 return NT_STATUS_NO_MEMORY;
2649 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2650 if (!r->out.old_val->buf) {
2651 return NT_STATUS_NO_MEMORY;
2653 r->out.old_val->buf->size = crypt_secret.length;
2654 r->out.old_val->buf->length = crypt_secret.length;
2655 r->out.old_val->buf->data = crypt_secret.data;
2659 if (r->in.old_mtime) {
2660 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2661 if (!r->out.old_mtime) {
2662 return NT_STATUS_NO_MEMORY;
2664 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
2667 if (r->in.new_val) {
2668 const struct ldb_val *new_val;
2669 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2670 if (!r->out.new_val) {
2671 return NT_STATUS_NO_MEMORY;
2674 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2676 if (new_val && new_val->length) {
2677 secret.data = new_val->data;
2678 secret.length = new_val->length;
2681 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2682 if (!crypt_secret.length) {
2683 return NT_STATUS_NO_MEMORY;
2685 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2686 if (!r->out.new_val->buf) {
2687 return NT_STATUS_NO_MEMORY;
2689 r->out.new_val->buf->length = crypt_secret.length;
2690 r->out.new_val->buf->size = crypt_secret.length;
2691 r->out.new_val->buf->data = crypt_secret.data;
2695 if (r->in.new_mtime) {
2696 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2697 if (!r->out.new_mtime) {
2698 return NT_STATUS_NO_MEMORY;
2700 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2703 return NT_STATUS_OK;
2710 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
2711 TALLOC_CTX *mem_ctx,
2712 struct lsa_LookupPrivValue *r)
2714 struct dcesrv_handle *h;
2715 struct lsa_policy_state *state;
2718 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2722 id = sec_privilege_id(r->in.name->string);
2724 return NT_STATUS_NO_SUCH_PRIVILEGE;
2727 r->out.luid->low = id;
2728 r->out.luid->high = 0;
2730 return NT_STATUS_OK;
2737 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
2738 TALLOC_CTX *mem_ctx,
2739 struct lsa_LookupPrivName *r)
2741 struct dcesrv_handle *h;
2742 struct lsa_policy_state *state;
2743 const char *privname;
2745 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2749 if (r->in.luid->high != 0) {
2750 return NT_STATUS_NO_SUCH_PRIVILEGE;
2753 privname = sec_privilege_name(r->in.luid->low);
2754 if (privname == NULL) {
2755 return NT_STATUS_NO_SUCH_PRIVILEGE;
2758 r->out.name = talloc(mem_ctx, struct lsa_StringLarge);
2759 if (r->out.name == NULL) {
2760 return NT_STATUS_NO_MEMORY;
2762 r->out.name->string = privname;
2764 return NT_STATUS_OK;
2769 lsa_LookupPrivDisplayName
2771 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
2772 TALLOC_CTX *mem_ctx,
2773 struct lsa_LookupPrivDisplayName *r)
2775 struct dcesrv_handle *h;
2776 struct lsa_policy_state *state;
2779 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2783 id = sec_privilege_id(r->in.name->string);
2785 return NT_STATUS_NO_SUCH_PRIVILEGE;
2788 r->out.disp_name = talloc(mem_ctx, struct lsa_StringLarge);
2789 if (r->out.disp_name == NULL) {
2790 return NT_STATUS_NO_MEMORY;
2793 r->out.disp_name->string = sec_privilege_display_name(id, r->in.language_id);
2794 if (r->out.disp_name->string == NULL) {
2795 return NT_STATUS_INTERNAL_ERROR;
2798 return NT_STATUS_OK;
2805 static NTSTATUS dcesrv_lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2806 struct lsa_DeleteObject *r)
2808 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2813 lsa_EnumAccountsWithUserRight
2815 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
2816 TALLOC_CTX *mem_ctx,
2817 struct lsa_EnumAccountsWithUserRight *r)
2819 struct dcesrv_handle *h;
2820 struct lsa_policy_state *state;
2822 struct ldb_message **res;
2823 const char * const attrs[] = { "objectSid", NULL};
2824 const char *privname;
2826 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2830 if (r->in.name == NULL) {
2831 return NT_STATUS_NO_SUCH_PRIVILEGE;
2834 privname = r->in.name->string;
2835 if (sec_privilege_id(privname) == -1) {
2836 return NT_STATUS_NO_SUCH_PRIVILEGE;
2839 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
2840 "privilege=%s", privname);
2842 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2845 return NT_STATUS_NO_MORE_ENTRIES;
2848 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2849 if (r->out.sids->sids == NULL) {
2850 return NT_STATUS_NO_MEMORY;
2852 for (i=0;i<ret;i++) {
2853 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2854 res[i], "objectSid");
2855 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2857 r->out.sids->num_sids = ret;
2859 return NT_STATUS_OK;
2864 lsa_AddAccountRights
2866 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
2867 TALLOC_CTX *mem_ctx,
2868 struct lsa_AddAccountRights *r)
2870 struct dcesrv_handle *h;
2871 struct lsa_policy_state *state;
2873 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2877 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2879 r->in.sid, r->in.rights);
2884 lsa_RemoveAccountRights
2886 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
2887 TALLOC_CTX *mem_ctx,
2888 struct lsa_RemoveAccountRights *r)
2890 struct dcesrv_handle *h;
2891 struct lsa_policy_state *state;
2893 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2897 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2898 LDB_FLAG_MOD_DELETE,
2899 r->in.sid, r->in.rights);
2904 lsa_StorePrivateData
2906 static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2907 struct lsa_StorePrivateData *r)
2909 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2914 lsa_RetrievePrivateData
2916 static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2917 struct lsa_RetrievePrivateData *r)
2919 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2926 static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2927 struct lsa_GetUserName *r)
2929 NTSTATUS status = NT_STATUS_OK;
2930 const char *account_name;
2931 const char *authority_name;
2932 struct lsa_String *_account_name;
2933 struct lsa_StringPointer *_authority_name = NULL;
2935 /* this is what w2k3 does */
2936 r->out.account_name = r->in.account_name;
2937 r->out.authority_name = r->in.authority_name;
2939 if (r->in.account_name && r->in.account_name->string) {
2940 return NT_STATUS_INVALID_PARAMETER;
2943 if (r->in.authority_name &&
2944 r->in.authority_name->string &&
2945 r->in.authority_name->string->string) {
2946 return NT_STATUS_INVALID_PARAMETER;
2949 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
2950 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
2952 _account_name = talloc(mem_ctx, struct lsa_String);
2953 NT_STATUS_HAVE_NO_MEMORY(_account_name);
2954 _account_name->string = account_name;
2956 if (r->in.authority_name) {
2957 _authority_name = talloc(mem_ctx, struct lsa_StringPointer);
2958 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
2959 _authority_name->string = talloc(mem_ctx, struct lsa_String);
2960 NT_STATUS_HAVE_NO_MEMORY(_authority_name->string);
2961 _authority_name->string->string = authority_name;
2964 r->out.account_name = _account_name;
2965 r->out.authority_name = _authority_name;
2973 static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
2974 TALLOC_CTX *mem_ctx,
2975 struct lsa_SetInfoPolicy2 *r)
2977 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2981 lsa_QueryDomainInformationPolicy
2983 static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2984 TALLOC_CTX *mem_ctx,
2985 struct lsa_QueryDomainInformationPolicy *r)
2987 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2991 lsa_SetDomInfoPolicy
2993 static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2994 TALLOC_CTX *mem_ctx,
2995 struct lsa_SetDomainInformationPolicy *r)
2997 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3003 static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
3004 TALLOC_CTX *mem_ctx,
3005 struct lsa_TestCall *r)
3007 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3011 lookup a SID for 1 name
3013 static NTSTATUS dcesrv_lsa_lookup_name(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
3014 const char *name, struct dom_sid **sid, uint32_t *atype)
3017 struct ldb_message **res;
3018 const char * const attrs[] = { "objectSid", "sAMAccountType", NULL};
3021 p = strchr_m(name, '\\');
3023 /* TODO: properly parse the domain prefix here, and use it to
3028 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs, "sAMAccountName=%s", ldb_binary_encode_string(mem_ctx, name));
3030 *sid = samdb_result_dom_sid(mem_ctx, res[0], "objectSid");
3032 return NT_STATUS_INVALID_SID;
3035 *atype = samdb_result_uint(res[0], "sAMAccountType", 0);
3037 return NT_STATUS_OK;
3040 /* need to add a call into sidmap to check for a allocated sid */
3042 return NT_STATUS_INVALID_SID;
3049 static NTSTATUS dcesrv_lsa_LookupNames3(struct dcesrv_call_state *dce_call,
3050 TALLOC_CTX *mem_ctx,
3051 struct lsa_LookupNames3 *r)
3053 struct lsa_policy_state *policy_state;
3054 struct dcesrv_handle *policy_handle;
3056 NTSTATUS status = NT_STATUS_OK;
3058 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
3060 policy_state = policy_handle->data;
3062 r->out.domains = NULL;
3064 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
3065 if (r->out.domains == NULL) {
3066 return NT_STATUS_NO_MEMORY;
3069 r->out.sids = talloc_zero(mem_ctx, struct lsa_TransSidArray3);
3070 if (r->out.sids == NULL) {
3071 return NT_STATUS_NO_MEMORY;
3076 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid3,
3078 if (r->out.sids->sids == NULL) {
3079 return NT_STATUS_NO_MEMORY;
3082 for (i=0;i<r->in.num_names;i++) {
3083 const char *name = r->in.names[i].string;
3084 struct dom_sid *sid;
3085 uint32_t atype, rtype, sid_index;
3088 r->out.sids->count++;
3091 r->out.sids->sids[i].sid_type = SID_NAME_UNKNOWN;
3092 r->out.sids->sids[i].sid = NULL;
3093 r->out.sids->sids[i].sid_index = 0xFFFFFFFF;
3094 r->out.sids->sids[i].unknown = 0;
3096 status2 = dcesrv_lsa_lookup_name(policy_state, mem_ctx, name, &sid, &atype);
3097 if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
3098 status = STATUS_SOME_UNMAPPED;
3102 rtype = samdb_atype_map(atype);
3103 if (rtype == SID_NAME_UNKNOWN) {
3104 status = STATUS_SOME_UNMAPPED;
3108 status2 = dcesrv_lsa_authority_list(policy_state, mem_ctx, sid, r->out.domains, &sid_index);
3109 if (!NT_STATUS_IS_OK(status2)) {
3113 r->out.sids->sids[i].sid_type = rtype;
3114 r->out.sids->sids[i].sid = sid;
3115 r->out.sids->sids[i].sid_index = sid_index;
3116 r->out.sids->sids[i].unknown = 0;
3125 Identical to LookupNames3, but doesn't take a policy handle
3128 static NTSTATUS dcesrv_lsa_LookupNames4(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3129 struct lsa_LookupNames4 *r)
3131 struct lsa_LookupNames3 r2;
3132 struct lsa_OpenPolicy2 pol;
3134 struct dcesrv_handle *h;
3136 /* No policy handle on the wire, so make one up here */
3137 r2.in.handle = talloc(mem_ctx, struct policy_handle);
3138 if (!r2.in.handle) {
3139 return NT_STATUS_NO_MEMORY;
3142 pol.out.handle = r2.in.handle;
3143 pol.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3145 pol.in.system_name = NULL;
3146 status = dcesrv_lsa_OpenPolicy2(dce_call, mem_ctx, &pol);
3147 if (!NT_STATUS_IS_OK(status)) {
3151 /* ensure this handle goes away at the end of this call */
3152 DCESRV_PULL_HANDLE(h, r2.in.handle, LSA_HANDLE_POLICY);
3153 talloc_steal(mem_ctx, h);
3155 r2.in.num_names = r->in.num_names;
3156 r2.in.names = r->in.names;
3157 r2.in.sids = r->in.sids;
3158 r2.in.count = r->in.count;
3159 r2.in.unknown1 = r->in.unknown1;
3160 r2.in.unknown2 = r->in.unknown2;
3161 r2.out.domains = r->out.domains;
3162 r2.out.sids = r->out.sids;
3163 r2.out.count = r->out.count;
3165 status = dcesrv_lsa_LookupNames3(dce_call, mem_ctx, &r2);
3166 if (dce_call->fault_code != 0) {
3170 r->out.domains = r2.out.domains;
3171 r->out.sids = r2.out.sids;
3172 r->out.count = r2.out.count;
3179 static NTSTATUS dcesrv_lsa_LookupNames2(struct dcesrv_call_state *dce_call,
3180 TALLOC_CTX *mem_ctx,
3181 struct lsa_LookupNames2 *r)
3183 struct lsa_policy_state *state;
3184 struct dcesrv_handle *h;
3186 NTSTATUS status = NT_STATUS_OK;
3188 r->out.domains = NULL;
3190 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3194 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
3195 if (r->out.domains == NULL) {
3196 return NT_STATUS_NO_MEMORY;
3199 r->out.sids = talloc_zero(mem_ctx, struct lsa_TransSidArray2);
3200 if (r->out.sids == NULL) {
3201 return NT_STATUS_NO_MEMORY;
3206 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid2,
3208 if (r->out.sids->sids == NULL) {
3209 return NT_STATUS_NO_MEMORY;
3212 for (i=0;i<r->in.num_names;i++) {
3213 const char *name = r->in.names[i].string;
3214 struct dom_sid *sid;
3215 uint32_t atype, rtype, sid_index;
3218 r->out.sids->count++;
3221 r->out.sids->sids[i].sid_type = SID_NAME_UNKNOWN;
3222 r->out.sids->sids[i].rid = 0xFFFFFFFF;
3223 r->out.sids->sids[i].sid_index = 0xFFFFFFFF;
3224 r->out.sids->sids[i].unknown = 0;
3226 status2 = dcesrv_lsa_lookup_name(state, mem_ctx, name, &sid, &atype);
3227 if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
3228 status = STATUS_SOME_UNMAPPED;
3232 rtype = samdb_atype_map(atype);
3233 if (rtype == SID_NAME_UNKNOWN) {
3234 status = STATUS_SOME_UNMAPPED;
3238 status2 = dcesrv_lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
3239 if (!NT_STATUS_IS_OK(status2)) {
3243 r->out.sids->sids[i].sid_type = rtype;
3244 r->out.sids->sids[i].rid = sid->sub_auths[sid->num_auths-1];
3245 r->out.sids->sids[i].sid_index = sid_index;
3246 r->out.sids->sids[i].unknown = 0;
3255 static NTSTATUS dcesrv_lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3256 struct lsa_LookupNames *r)
3258 struct lsa_LookupNames2 r2;
3262 r2.in.handle = r->in.handle;
3263 r2.in.num_names = r->in.num_names;
3264 r2.in.names = r->in.names;
3266 r2.in.level = r->in.level;
3267 r2.in.count = r->in.count;
3270 r2.out.count = r->out.count;
3272 status = dcesrv_lsa_LookupNames2(dce_call, mem_ctx, &r2);
3273 if (dce_call->fault_code != 0) {
3277 r->out.domains = r2.out.domains;
3278 r->out.sids = talloc(mem_ctx, struct lsa_TransSidArray);
3279 if (r->out.sids == NULL) {
3280 return NT_STATUS_NO_MEMORY;
3282 r->out.sids->count = r2.out.sids->count;
3283 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid,
3284 r->out.sids->count);
3285 if (r->out.sids->sids == NULL) {
3286 return NT_STATUS_NO_MEMORY;
3288 for (i=0;i<r->out.sids->count;i++) {
3289 r->out.sids->sids[i].sid_type = r2.out.sids->sids[i].sid_type;
3290 r->out.sids->sids[i].rid = r2.out.sids->sids[i].rid;
3291 r->out.sids->sids[i].sid_index = r2.out.sids->sids[i].sid_index;
3300 static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3301 struct lsa_CREDRWRITE *r)
3303 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3310 static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3311 struct lsa_CREDRREAD *r)
3313 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3320 static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3321 struct lsa_CREDRENUMERATE *r)
3323 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3328 lsa_CREDRWRITEDOMAINCREDENTIALS
3330 static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3331 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3333 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3338 lsa_CREDRREADDOMAINCREDENTIALS
3340 static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3341 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3343 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3350 static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3351 struct lsa_CREDRDELETE *r)
3353 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3358 lsa_CREDRGETTARGETINFO
3360 static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3361 struct lsa_CREDRGETTARGETINFO *r)
3363 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3368 lsa_CREDRPROFILELOADED
3370 static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3371 struct lsa_CREDRPROFILELOADED *r)
3373 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3378 lsa_CREDRGETSESSIONTYPES
3380 static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3381 struct lsa_CREDRGETSESSIONTYPES *r)
3383 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3388 lsa_LSARREGISTERAUDITEVENT
3390 static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3391 struct lsa_LSARREGISTERAUDITEVENT *r)
3393 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3398 lsa_LSARGENAUDITEVENT
3400 static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3401 struct lsa_LSARGENAUDITEVENT *r)
3403 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3408 lsa_LSARUNREGISTERAUDITEVENT
3410 static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3411 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3413 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3418 lsa_lsaRQueryForestTrustInformation
3420 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3421 struct lsa_lsaRQueryForestTrustInformation *r)
3423 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3428 lsa_LSARSETFORESTTRUSTINFORMATION
3430 static NTSTATUS dcesrv_lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3431 struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
3433 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3440 static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3441 struct lsa_CREDRRENAME *r)
3443 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3449 lsa_LSAROPENPOLICYSCE
3451 static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3452 struct lsa_LSAROPENPOLICYSCE *r)
3454 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3459 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
3461 static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3462 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
3464 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3469 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
3471 static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3472 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
3474 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3479 lsa_LSARADTREPORTSECURITYEVENT
3481 static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3482 struct lsa_LSARADTREPORTSECURITYEVENT *r)
3484 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3488 /* include the generated boilerplate */
3489 #include "librpc/gen_ndr/ndr_lsa_s.c"
3493 /*****************************************
3494 NOTE! The remaining calls below were
3495 removed in w2k3, so the DCESRV_FAULT()
3496 replies are the correct implementation. Do
3497 not try and fill these in with anything else
3498 ******************************************/
3501 dssetup_DsRoleDnsNameToFlatName
3503 static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3504 struct dssetup_DsRoleDnsNameToFlatName *r)
3506 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3511 dssetup_DsRoleDcAsDc
3513 static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3514 struct dssetup_DsRoleDcAsDc *r)
3516 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3521 dssetup_DsRoleDcAsReplica
3523 static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3524 struct dssetup_DsRoleDcAsReplica *r)
3526 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3531 dssetup_DsRoleDemoteDc
3533 static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3534 struct dssetup_DsRoleDemoteDc *r)
3536 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3541 dssetup_DsRoleGetDcOperationProgress
3543 static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3544 struct dssetup_DsRoleGetDcOperationProgress *r)
3546 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3551 dssetup_DsRoleGetDcOperationResults
3553 static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3554 struct dssetup_DsRoleGetDcOperationResults *r)
3556 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3561 dssetup_DsRoleCancel
3563 static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3564 struct dssetup_DsRoleCancel *r)
3566 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3571 dssetup_DsRoleServerSaveStateForUpgrade
3573 static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3574 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
3576 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3581 dssetup_DsRoleUpgradeDownlevelServer
3583 static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3584 struct dssetup_DsRoleUpgradeDownlevelServer *r)
3586 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3591 dssetup_DsRoleAbortDownlevelServerUpgrade
3593 static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3594 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
3596 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3600 /* include the generated boilerplate */
3601 #include "librpc/gen_ndr/ndr_dssetup_s.c"
3603 NTSTATUS dcerpc_server_lsa_init(void)
3607 ret = dcerpc_server_dssetup_init();
3608 if (!NT_STATUS_IS_OK(ret)) {
3611 ret = dcerpc_server_lsarpc_init();
3612 if (!NT_STATUS_IS_OK(ret)) {