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 *builtin_dn;
57 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 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 struct ldb_dn *partitions_basedn;
275 struct ldb_result *dom_res;
276 const char *dom_attrs[] = {
283 struct ldb_result *ref_res;
284 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(mem_ctx, 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 ret = ldb_search_exp_fmt(state->sam_ldb, state, &ref_res,
341 partitions_basedn, LDB_SCOPE_SUBTREE, ref_attrs,
342 "(&(objectclass=crossRef)(ncName=%s))",
343 ldb_dn_get_linearized(state->domain_dn));
345 if (ret != LDB_SUCCESS) {
346 talloc_free(ref_res);
347 return NT_STATUS_INVALID_SYSTEM_SERVICE;
349 if (ref_res->count != 1) {
350 talloc_free(ref_res);
351 return NT_STATUS_NO_SUCH_DOMAIN;
354 state->domain_name = ldb_msg_find_attr_as_string(ref_res->msgs[0], "nETBIOSName", NULL);
355 if (!state->domain_name) {
356 talloc_free(ref_res);
357 return NT_STATUS_NO_SUCH_DOMAIN;
359 talloc_steal(state, state->domain_name);
361 state->domain_dns = ldb_msg_find_attr_as_string(ref_res->msgs[0], "dnsRoot", NULL);
362 if (!state->domain_dns) {
363 talloc_free(ref_res);
364 return NT_STATUS_NO_SUCH_DOMAIN;
366 talloc_steal(state, state->domain_dns);
368 talloc_free(ref_res);
370 /* work out the builtin_dn - useful for so many calls its worth
372 state->builtin_dn = samdb_search_dn(state->sam_ldb, state, state->domain_dn, "(objectClass=builtinDomain)");
373 if (!state->builtin_dn) {
374 return NT_STATUS_NO_SUCH_DOMAIN;
377 /* work out the system_dn - useful for so many calls its worth
379 state->system_dn = samdb_search_dn(state->sam_ldb, state,
380 state->domain_dn, "(&(objectClass=container)(cn=System))");
381 if (!state->system_dn) {
382 return NT_STATUS_NO_SUCH_DOMAIN;
385 state->builtin_sid = dom_sid_parse_talloc(state, SID_BUILTIN);
386 if (!state->builtin_sid) {
387 return NT_STATUS_NO_SUCH_DOMAIN;
396 dssetup_DsRoleGetPrimaryDomainInformation
398 This is not an LSA call, but is the only call left on the DSSETUP
399 pipe (after the pipe was truncated), and needs lsa_get_policy_state
401 static WERROR dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state *dce_call,
403 struct dssetup_DsRoleGetPrimaryDomainInformation *r)
405 union dssetup_DsRoleInfo *info;
407 info = talloc(mem_ctx, union dssetup_DsRoleInfo);
408 W_ERROR_HAVE_NO_MEMORY(info);
410 switch (r->in.level) {
411 case DS_ROLE_BASIC_INFORMATION:
413 enum dssetup_DsRole role = DS_ROLE_STANDALONE_SERVER;
415 const char *domain = NULL;
416 const char *dns_domain = NULL;
417 const char *forest = NULL;
418 struct GUID domain_guid;
419 struct lsa_policy_state *state;
421 NTSTATUS status = lsa_get_policy_state(dce_call, mem_ctx, &state);
422 if (!NT_STATUS_IS_OK(status)) {
423 return ntstatus_to_werror(status);
426 ZERO_STRUCT(domain_guid);
428 switch (lp_server_role()) {
429 case ROLE_STANDALONE:
430 role = DS_ROLE_STANDALONE_SERVER;
432 case ROLE_DOMAIN_MEMBER:
433 role = DS_ROLE_MEMBER_SERVER;
435 case ROLE_DOMAIN_CONTROLLER:
436 if (samdb_is_pdc(state->sam_ldb)) {
437 role = DS_ROLE_PRIMARY_DC;
439 role = DS_ROLE_BACKUP_DC;
444 switch (lp_server_role()) {
445 case ROLE_STANDALONE:
446 domain = talloc_strdup(mem_ctx, lp_workgroup());
447 W_ERROR_HAVE_NO_MEMORY(domain);
449 case ROLE_DOMAIN_MEMBER:
450 domain = talloc_strdup(mem_ctx, lp_workgroup());
451 W_ERROR_HAVE_NO_MEMORY(domain);
452 /* TODO: what is with dns_domain and forest and guid? */
454 case ROLE_DOMAIN_CONTROLLER:
455 flags = DS_ROLE_PRIMARY_DS_RUNNING;
457 if (state->mixed_domain == 1) {
458 flags |= DS_ROLE_PRIMARY_DS_MIXED_MODE;
461 domain = state->domain_name;
462 dns_domain = state->domain_dns;
463 forest = state->domain_dns;
465 domain_guid = state->domain_guid;
466 flags |= DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT;
470 info->basic.role = role;
471 info->basic.flags = flags;
472 info->basic.domain = domain;
473 info->basic.dns_domain = dns_domain;
474 info->basic.forest = forest;
475 info->basic.domain_guid = domain_guid;
480 case DS_ROLE_UPGRADE_STATUS:
482 info->upgrade.upgrading = DS_ROLE_NOT_UPGRADING;
483 info->upgrade.previous_role = DS_ROLE_PREVIOUS_UNKNOWN;
488 case DS_ROLE_OP_STATUS:
490 info->opstatus.status = DS_ROLE_OP_IDLE;
496 return WERR_INVALID_PARAM;
499 return WERR_INVALID_PARAM;
505 static NTSTATUS lsa_OpenPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
506 struct lsa_OpenPolicy2 *r)
509 struct lsa_policy_state *state;
510 struct dcesrv_handle *handle;
512 ZERO_STRUCTP(r->out.handle);
514 status = lsa_get_policy_state(dce_call, mem_ctx, &state);
515 if (!NT_STATUS_IS_OK(status)) {
519 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_POLICY);
521 return NT_STATUS_NO_MEMORY;
524 handle->data = talloc_steal(handle, state);
526 state->access_mask = r->in.access_mask;
527 state->handle = handle;
528 *r->out.handle = handle->wire_handle;
530 /* note that we have completely ignored the attr element of
531 the OpenPolicy. As far as I can tell, this is what w2k3
539 a wrapper around lsa_OpenPolicy2
541 static NTSTATUS lsa_OpenPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
542 struct lsa_OpenPolicy *r)
544 struct lsa_OpenPolicy2 r2;
546 r2.in.system_name = NULL;
547 r2.in.attr = r->in.attr;
548 r2.in.access_mask = r->in.access_mask;
549 r2.out.handle = r->out.handle;
551 return lsa_OpenPolicy2(dce_call, mem_ctx, &r2);
558 fill in the AccountDomain info
560 static NTSTATUS lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
561 struct lsa_DomainInfo *info)
563 info->name.string = state->domain_name;
564 info->sid = state->domain_sid;
570 fill in the DNS domain info
572 static NTSTATUS lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
573 struct lsa_DnsDomainInfo *info)
575 info->name.string = state->domain_name;
576 info->sid = state->domain_sid;
577 info->dns_domain.string = state->domain_dns;
578 info->dns_forest.string = state->domain_dns;
579 info->domain_guid = state->domain_guid;
587 static NTSTATUS lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
588 struct lsa_QueryInfoPolicy2 *r)
590 struct lsa_policy_state *state;
591 struct dcesrv_handle *h;
595 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
599 r->out.info = talloc(mem_ctx, union lsa_PolicyInformation);
601 return NT_STATUS_NO_MEMORY;
604 ZERO_STRUCTP(r->out.info);
606 switch (r->in.level) {
607 case LSA_POLICY_INFO_DOMAIN:
608 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
609 return lsa_info_AccountDomain(state, mem_ctx, &r->out.info->account_domain);
611 case LSA_POLICY_INFO_DNS:
612 return lsa_info_DNS(state, mem_ctx, &r->out.info->dns);
615 return NT_STATUS_INVALID_INFO_CLASS;
621 static NTSTATUS lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
622 struct lsa_QueryInfoPolicy *r)
624 struct lsa_QueryInfoPolicy2 r2;
627 r2.in.handle = r->in.handle;
628 r2.in.level = r->in.level;
630 status = lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
632 r->out.info = r2.out.info;
640 static NTSTATUS lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
641 struct lsa_SetInfoPolicy *r)
643 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
650 static NTSTATUS lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
651 struct lsa_ClearAuditLog *r)
653 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
660 static NTSTATUS lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
661 struct lsa_CreateAccount *r)
663 struct lsa_account_state *astate;
665 struct lsa_policy_state *state;
666 struct dcesrv_handle *h, *ah;
668 ZERO_STRUCTP(r->out.acct_handle);
670 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
674 astate = talloc(dce_call->conn, struct lsa_account_state);
675 if (astate == NULL) {
676 return NT_STATUS_NO_MEMORY;
679 astate->account_sid = dom_sid_dup(astate, r->in.sid);
680 if (astate->account_sid == NULL) {
682 return NT_STATUS_NO_MEMORY;
685 astate->policy = talloc_reference(astate, state);
686 astate->access_mask = r->in.access_mask;
688 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
691 return NT_STATUS_NO_MEMORY;
694 ah->data = talloc_steal(ah, astate);
696 *r->out.acct_handle = ah->wire_handle;
705 static NTSTATUS lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
706 struct lsa_EnumAccounts *r)
708 struct dcesrv_handle *h;
709 struct lsa_policy_state *state;
711 struct ldb_message **res;
712 const char * const attrs[] = { "objectSid", NULL};
715 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
719 /* NOTE: This call must only return accounts that have at least
722 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
723 "(&(objectSid=*)(privilege=*))");
725 return NT_STATUS_NO_SUCH_USER;
728 if (*r->in.resume_handle >= ret) {
729 return NT_STATUS_NO_MORE_ENTRIES;
732 count = ret - *r->in.resume_handle;
733 if (count > r->in.num_entries) {
734 count = r->in.num_entries;
738 return NT_STATUS_NO_MORE_ENTRIES;
741 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, count);
742 if (r->out.sids->sids == NULL) {
743 return NT_STATUS_NO_MEMORY;
746 for (i=0;i<count;i++) {
747 r->out.sids->sids[i].sid =
748 samdb_result_dom_sid(r->out.sids->sids,
749 res[i + *r->in.resume_handle],
751 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
754 r->out.sids->num_sids = count;
755 *r->out.resume_handle = count + *r->in.resume_handle;
763 lsa_CreateTrustedDomainEx2
765 static NTSTATUS lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
767 struct lsa_CreateTrustedDomainEx2 *r)
769 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
773 lsa_CreateTrustedDomainEx
775 static NTSTATUS lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
777 struct lsa_CreateTrustedDomainEx *r)
779 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
783 lsa_CreateTrustedDomain
785 static NTSTATUS lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
786 struct lsa_CreateTrustedDomain *r)
788 struct dcesrv_handle *policy_handle;
789 struct lsa_policy_state *policy_state;
790 struct lsa_trusted_domain_state *trusted_domain_state;
791 struct dcesrv_handle *handle;
792 struct ldb_message **msgs, *msg;
793 const char *attrs[] = {
799 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
800 ZERO_STRUCTP(r->out.trustdom_handle);
802 policy_state = policy_handle->data;
804 if (!r->in.info->name.string) {
805 return NT_STATUS_INVALID_PARAMETER;
807 name = r->in.info->name.string;
809 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
810 if (!trusted_domain_state) {
811 return NT_STATUS_NO_MEMORY;
813 trusted_domain_state->policy = policy_state;
815 msg = ldb_msg_new(mem_ctx);
817 return NT_STATUS_NO_MEMORY;
820 /* search for the trusted_domain record */
821 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
822 mem_ctx, policy_state->system_dn, &msgs, attrs,
823 "(&(cn=%s)(objectclass=trustedDomain))",
824 ldb_binary_encode_string(mem_ctx, r->in.info->name.string));
826 return NT_STATUS_OBJECT_NAME_COLLISION;
829 if (ret < 0 || ret > 1) {
830 DEBUG(0,("Found %d records matching DN %s\n", ret,
831 ldb_dn_get_linearized(policy_state->system_dn)));
832 return NT_STATUS_INTERNAL_DB_CORRUPTION;
835 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
836 if ( ! ldb_dn_add_child_fmt(msg->dn, "sn=%s", r->in.info->name.string)) {
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_get_linearized(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_get_linearized(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_get_linearized(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_m(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_m(e1->netbios_name.string, e2->netbios_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_LookupSids2(struct dcesrv_call_state *dce_call,
1560 TALLOC_CTX *mem_ctx,
1561 struct lsa_LookupSids2 *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 Identical to LookupSids2, but doesn't take a policy handle
1648 static NTSTATUS lsa_LookupSids3(struct dcesrv_call_state *dce_call,
1649 TALLOC_CTX *mem_ctx,
1650 struct lsa_LookupSids3 *r)
1652 struct lsa_LookupSids2 r2;
1653 struct lsa_OpenPolicy2 pol;
1655 struct dcesrv_handle *h;
1657 /* No policy handle on the wire, so make one up here */
1658 r2.in.handle = talloc(mem_ctx, struct policy_handle);
1659 if (!r2.in.handle) {
1660 return NT_STATUS_NO_MEMORY;
1663 pol.out.handle = r2.in.handle;
1664 pol.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1666 pol.in.system_name = NULL;
1667 status = lsa_OpenPolicy2(dce_call, mem_ctx, &pol);
1668 if (!NT_STATUS_IS_OK(status)) {
1672 /* ensure this handle goes away at the end of this call */
1673 DCESRV_PULL_HANDLE(h, r2.in.handle, LSA_HANDLE_POLICY);
1674 talloc_steal(mem_ctx, h);
1676 r2.in.sids = r->in.sids;
1677 r2.in.names = r->in.names;
1678 r2.in.level = r->in.level;
1679 r2.in.count = r->in.count;
1680 r2.in.unknown1 = r->in.unknown1;
1681 r2.in.unknown2 = r->in.unknown2;
1682 r2.out.count = r->out.count;
1683 r2.out.names = r->out.names;
1685 status = lsa_LookupSids2(dce_call, mem_ctx, &r2);
1686 if (dce_call->fault_code != 0) {
1690 r->out.domains = r2.out.domains;
1691 r->out.names = r2.out.names;
1692 r->out.count = r2.out.count;
1701 static NTSTATUS lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1702 struct lsa_LookupSids *r)
1704 struct lsa_LookupSids2 r2;
1708 r2.in.handle = r->in.handle;
1709 r2.in.sids = r->in.sids;
1711 r2.in.level = r->in.level;
1712 r2.in.count = r->in.count;
1715 r2.out.count = r->out.count;
1716 r2.out.names = NULL;
1718 status = lsa_LookupSids2(dce_call, mem_ctx, &r2);
1719 if (dce_call->fault_code != 0) {
1723 r->out.domains = r2.out.domains;
1724 if (!r2.out.names) {
1725 r->out.names = NULL;
1729 r->out.names = talloc(mem_ctx, struct lsa_TransNameArray);
1730 if (r->out.names == NULL) {
1731 return NT_STATUS_NO_MEMORY;
1733 r->out.names->count = r2.out.names->count;
1734 r->out.names->names = talloc_array(r->out.names, struct lsa_TranslatedName,
1735 r->out.names->count);
1736 if (r->out.names->names == NULL) {
1737 return NT_STATUS_NO_MEMORY;
1739 for (i=0;i<r->out.names->count;i++) {
1740 r->out.names->names[i].sid_type = r2.out.names->names[i].sid_type;
1741 r->out.names->names[i].name.string = r2.out.names->names[i].name.string;
1742 r->out.names->names[i].sid_index = r2.out.names->names[i].sid_index;
1752 static NTSTATUS lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1753 struct lsa_OpenAccount *r)
1755 struct dcesrv_handle *h, *ah;
1756 struct lsa_policy_state *state;
1757 struct lsa_account_state *astate;
1759 ZERO_STRUCTP(r->out.acct_handle);
1761 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1765 astate = talloc(dce_call->conn, struct lsa_account_state);
1766 if (astate == NULL) {
1767 return NT_STATUS_NO_MEMORY;
1770 astate->account_sid = dom_sid_dup(astate, r->in.sid);
1771 if (astate->account_sid == NULL) {
1772 talloc_free(astate);
1773 return NT_STATUS_NO_MEMORY;
1776 astate->policy = talloc_reference(astate, state);
1777 astate->access_mask = r->in.access_mask;
1779 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
1781 talloc_free(astate);
1782 return NT_STATUS_NO_MEMORY;
1785 ah->data = talloc_steal(ah, astate);
1787 *r->out.acct_handle = ah->wire_handle;
1789 return NT_STATUS_OK;
1794 lsa_EnumPrivsAccount
1796 static NTSTATUS lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
1797 TALLOC_CTX *mem_ctx,
1798 struct lsa_EnumPrivsAccount *r)
1800 struct dcesrv_handle *h;
1801 struct lsa_account_state *astate;
1803 struct ldb_message **res;
1804 const char * const attrs[] = { "privilege", NULL};
1805 struct ldb_message_element *el;
1808 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1812 r->out.privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
1813 r->out.privs->count = 0;
1814 r->out.privs->unknown = 0;
1815 r->out.privs->set = NULL;
1817 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
1818 if (sidstr == NULL) {
1819 return NT_STATUS_NO_MEMORY;
1822 ret = gendb_search(astate->policy->sam_ldb, mem_ctx, NULL, &res, attrs,
1823 "objectSid=%s", sidstr);
1825 return NT_STATUS_OK;
1828 el = ldb_msg_find_element(res[0], "privilege");
1829 if (el == NULL || el->num_values == 0) {
1830 return NT_STATUS_OK;
1833 r->out.privs->set = talloc_array(r->out.privs,
1834 struct lsa_LUIDAttribute, el->num_values);
1835 if (r->out.privs->set == NULL) {
1836 return NT_STATUS_NO_MEMORY;
1839 for (i=0;i<el->num_values;i++) {
1840 int id = sec_privilege_id((const char *)el->values[i].data);
1842 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1844 r->out.privs->set[i].attribute = 0;
1845 r->out.privs->set[i].luid.low = id;
1846 r->out.privs->set[i].luid.high = 0;
1849 r->out.privs->count = el->num_values;
1851 return NT_STATUS_OK;
1855 lsa_EnumAccountRights
1857 static NTSTATUS lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
1858 TALLOC_CTX *mem_ctx,
1859 struct lsa_EnumAccountRights *r)
1861 struct dcesrv_handle *h;
1862 struct lsa_policy_state *state;
1864 struct ldb_message **res;
1865 const char * const attrs[] = { "privilege", NULL};
1867 struct ldb_message_element *el;
1869 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1873 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
1874 if (sidstr == NULL) {
1875 return NT_STATUS_NO_MEMORY;
1878 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
1879 "(&(objectSid=%s)(privilege=*))", sidstr);
1881 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1884 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1887 DEBUG(3, ("searching for account rights for SID: %s failed: %s",
1888 dom_sid_string(mem_ctx, r->in.sid),
1889 ldb_errstring(state->sam_ldb)));
1890 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1893 el = ldb_msg_find_element(res[0], "privilege");
1894 if (el == NULL || el->num_values == 0) {
1895 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1898 r->out.rights->count = el->num_values;
1899 r->out.rights->names = talloc_array(r->out.rights,
1900 struct lsa_StringLarge, r->out.rights->count);
1901 if (r->out.rights->names == NULL) {
1902 return NT_STATUS_NO_MEMORY;
1905 for (i=0;i<el->num_values;i++) {
1906 r->out.rights->names[i].string = (const char *)el->values[i].data;
1909 return NT_STATUS_OK;
1915 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
1917 static NTSTATUS lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
1918 TALLOC_CTX *mem_ctx,
1919 struct lsa_policy_state *state,
1921 struct dom_sid *sid,
1922 const struct lsa_RightSet *rights)
1925 struct ldb_message *msg;
1926 struct ldb_message_element *el;
1928 struct lsa_EnumAccountRights r2;
1930 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, sid);
1931 if (sidstr == NULL) {
1932 return NT_STATUS_NO_MEMORY;
1935 msg = ldb_msg_new(mem_ctx);
1937 return NT_STATUS_NO_MEMORY;
1940 msg->dn = samdb_search_dn(state->sam_ldb, mem_ctx,
1941 NULL, "objectSid=%s", sidstr);
1942 if (msg->dn == NULL) {
1944 if (ldb_flag == LDB_FLAG_MOD_DELETE) {
1945 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1947 status = samdb_create_foreign_security_principal(state->sam_ldb, mem_ctx,
1949 if (!NT_STATUS_IS_OK(status)) {
1952 return NT_STATUS_NO_SUCH_USER;
1955 if (ldb_msg_add_empty(msg, "privilege", ldb_flag, NULL)) {
1956 return NT_STATUS_NO_MEMORY;
1959 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1962 r2.in.handle = &state->handle->wire_handle;
1964 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
1966 status = lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1967 if (!NT_STATUS_IS_OK(status)) {
1968 ZERO_STRUCTP(r2.out.rights);
1972 for (i=0;i<rights->count;i++) {
1973 if (sec_privilege_id(rights->names[i].string) == -1) {
1974 return NT_STATUS_NO_SUCH_PRIVILEGE;
1977 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1979 for (j=0;j<r2.out.rights->count;j++) {
1980 if (strcasecmp_m(r2.out.rights->names[j].string,
1981 rights->names[i].string) == 0) {
1985 if (j != r2.out.rights->count) continue;
1988 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
1989 if (ret != LDB_SUCCESS) {
1990 return NT_STATUS_NO_MEMORY;
1994 el = ldb_msg_find_element(msg, "privilege");
1996 return NT_STATUS_OK;
1999 ret = samdb_modify(state->sam_ldb, mem_ctx, msg);
2001 if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
2002 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2004 DEBUG(3, ("Could not %s attributes from %s: %s",
2005 ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add",
2006 ldb_dn_get_linearized(msg->dn), ldb_errstring(state->sam_ldb)));
2007 return NT_STATUS_UNEXPECTED_IO_ERROR;
2010 return NT_STATUS_OK;
2014 lsa_AddPrivilegesToAccount
2016 static NTSTATUS lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2017 struct lsa_AddPrivilegesToAccount *r)
2019 struct lsa_RightSet rights;
2020 struct dcesrv_handle *h;
2021 struct lsa_account_state *astate;
2024 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2028 rights.count = r->in.privs->count;
2029 rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
2030 if (rights.names == NULL) {
2031 return NT_STATUS_NO_MEMORY;
2033 for (i=0;i<rights.count;i++) {
2034 int id = r->in.privs->set[i].luid.low;
2035 if (r->in.privs->set[i].luid.high) {
2036 return NT_STATUS_NO_SUCH_PRIVILEGE;
2038 rights.names[i].string = sec_privilege_name(id);
2039 if (rights.names[i].string == NULL) {
2040 return NT_STATUS_NO_SUCH_PRIVILEGE;
2044 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2045 LDB_FLAG_MOD_ADD, astate->account_sid,
2051 lsa_RemovePrivilegesFromAccount
2053 static NTSTATUS lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2054 struct lsa_RemovePrivilegesFromAccount *r)
2056 struct lsa_RightSet *rights;
2057 struct dcesrv_handle *h;
2058 struct lsa_account_state *astate;
2061 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2065 rights = talloc(mem_ctx, struct lsa_RightSet);
2067 if (r->in.remove_all == 1 &&
2068 r->in.privs == NULL) {
2069 struct lsa_EnumAccountRights r2;
2072 r2.in.handle = &astate->policy->handle->wire_handle;
2073 r2.in.sid = astate->account_sid;
2074 r2.out.rights = rights;
2076 status = lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
2077 if (!NT_STATUS_IS_OK(status)) {
2081 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2082 LDB_FLAG_MOD_DELETE, astate->account_sid,
2086 if (r->in.remove_all != 0) {
2087 return NT_STATUS_INVALID_PARAMETER;
2090 rights->count = r->in.privs->count;
2091 rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
2092 if (rights->names == NULL) {
2093 return NT_STATUS_NO_MEMORY;
2095 for (i=0;i<rights->count;i++) {
2096 int id = r->in.privs->set[i].luid.low;
2097 if (r->in.privs->set[i].luid.high) {
2098 return NT_STATUS_NO_SUCH_PRIVILEGE;
2100 rights->names[i].string = sec_privilege_name(id);
2101 if (rights->names[i].string == NULL) {
2102 return NT_STATUS_NO_SUCH_PRIVILEGE;
2106 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2107 LDB_FLAG_MOD_DELETE, astate->account_sid,
2113 lsa_GetQuotasForAccount
2115 static NTSTATUS lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2116 struct lsa_GetQuotasForAccount *r)
2118 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2123 lsa_SetQuotasForAccount
2125 static NTSTATUS lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2126 struct lsa_SetQuotasForAccount *r)
2128 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2133 lsa_GetSystemAccessAccount
2135 static NTSTATUS lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2136 struct lsa_GetSystemAccessAccount *r)
2138 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2143 lsa_SetSystemAccessAccount
2145 static NTSTATUS lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2146 struct lsa_SetSystemAccessAccount *r)
2148 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2155 static NTSTATUS lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2156 struct lsa_CreateSecret *r)
2158 struct dcesrv_handle *policy_handle;
2159 struct lsa_policy_state *policy_state;
2160 struct lsa_secret_state *secret_state;
2161 struct dcesrv_handle *handle;
2162 struct ldb_message **msgs, *msg;
2164 const char *attrs[] = {
2172 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2173 ZERO_STRUCTP(r->out.sec_handle);
2175 policy_state = policy_handle->data;
2177 if (!r->in.name.string) {
2178 return NT_STATUS_INVALID_PARAMETER;
2181 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2182 if (!secret_state) {
2183 return NT_STATUS_NO_MEMORY;
2185 secret_state->policy = policy_state;
2187 msg = ldb_msg_new(mem_ctx);
2189 return NT_STATUS_NO_MEMORY;
2192 if (strncmp("G$", r->in.name.string, 2) == 0) {
2194 name = &r->in.name.string[2];
2195 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
2196 secret_state->global = True;
2198 if (strlen(name) < 1) {
2199 return NT_STATUS_INVALID_PARAMETER;
2202 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
2203 /* search for the secret record */
2204 ret = gendb_search(secret_state->sam_ldb,
2205 mem_ctx, policy_state->system_dn, &msgs, attrs,
2206 "(&(cn=%s)(objectclass=secret))",
2209 return NT_STATUS_OBJECT_NAME_COLLISION;
2213 DEBUG(0,("Failure searching for CN=%s: %s\n",
2214 name2, ldb_errstring(secret_state->sam_ldb)));
2215 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2218 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
2219 if (!name2 || ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
2220 return NT_STATUS_NO_MEMORY;
2223 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
2226 secret_state->global = False;
2228 name = r->in.name.string;
2229 if (strlen(name) < 1) {
2230 return NT_STATUS_INVALID_PARAMETER;
2233 secret_state->sam_ldb = talloc_reference(secret_state, secrets_db_connect(mem_ctx));
2234 /* search for the secret record */
2235 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2236 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2238 "(&(cn=%s)(objectclass=secret))",
2239 ldb_binary_encode_string(mem_ctx, name));
2241 return NT_STATUS_OBJECT_NAME_COLLISION;
2245 DEBUG(0,("Failure searching for CN=%s: %s\n",
2246 name, ldb_errstring(secret_state->sam_ldb)));
2247 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2250 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name);
2251 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
2254 /* pull in all the template attributes. Note this is always from the global samdb */
2255 ret = samdb_copy_template(secret_state->policy->sam_ldb, msg,
2256 "(&(cn=TemplateSecret)(objectclass=secretTemplate))", &errstr);
2258 DEBUG(0,("Failed to load TemplateSecret from samdb: %s\n",
2260 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2263 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
2265 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
2267 /* create the secret */
2268 ret = samdb_add(secret_state->sam_ldb, mem_ctx, msg);
2270 DEBUG(0,("Failed to create secret record %s: %s\n",
2271 ldb_dn_get_linearized(msg->dn),
2272 ldb_errstring(secret_state->sam_ldb)));
2273 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2276 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2278 return NT_STATUS_NO_MEMORY;
2281 handle->data = talloc_steal(handle, secret_state);
2283 secret_state->access_mask = r->in.access_mask;
2284 secret_state->policy = talloc_reference(secret_state, policy_state);
2286 *r->out.sec_handle = handle->wire_handle;
2288 return NT_STATUS_OK;
2295 static NTSTATUS lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2296 struct lsa_OpenSecret *r)
2298 struct dcesrv_handle *policy_handle;
2300 struct lsa_policy_state *policy_state;
2301 struct lsa_secret_state *secret_state;
2302 struct dcesrv_handle *handle;
2303 struct ldb_message **msgs;
2304 const char *attrs[] = {
2312 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2313 ZERO_STRUCTP(r->out.sec_handle);
2314 policy_state = policy_handle->data;
2316 if (!r->in.name.string) {
2317 return NT_STATUS_INVALID_PARAMETER;
2320 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2321 if (!secret_state) {
2322 return NT_STATUS_NO_MEMORY;
2324 secret_state->policy = policy_state;
2326 if (strncmp("G$", r->in.name.string, 2) == 0) {
2327 name = &r->in.name.string[2];
2328 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
2329 secret_state->global = True;
2331 if (strlen(name) < 1) {
2332 return NT_STATUS_INVALID_PARAMETER;
2335 /* search for the secret record */
2336 ret = gendb_search(secret_state->sam_ldb,
2337 mem_ctx, policy_state->system_dn, &msgs, attrs,
2338 "(&(cn=%s Secret)(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_get_linearized(policy_state->system_dn)));
2347 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2351 secret_state->sam_ldb = talloc_reference(secret_state, secrets_db_connect(mem_ctx));
2353 secret_state->global = False;
2354 name = r->in.name.string;
2355 if (strlen(name) < 1) {
2356 return NT_STATUS_INVALID_PARAMETER;
2359 /* search for the secret record */
2360 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2361 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2363 "(&(cn=%s)(objectclass=secret))",
2364 ldb_binary_encode_string(mem_ctx, name));
2366 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2370 DEBUG(0,("Found %d records matching DN %s\n", ret,
2371 ldb_dn_get_linearized(policy_state->system_dn)));
2372 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2376 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
2378 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2380 return NT_STATUS_NO_MEMORY;
2383 handle->data = talloc_steal(handle, secret_state);
2385 secret_state->access_mask = r->in.access_mask;
2386 secret_state->policy = talloc_reference(secret_state, policy_state);
2388 *r->out.sec_handle = handle->wire_handle;
2390 return NT_STATUS_OK;
2397 static NTSTATUS lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2398 struct lsa_SetSecret *r)
2401 struct dcesrv_handle *h;
2402 struct lsa_secret_state *secret_state;
2403 struct ldb_message *msg;
2404 DATA_BLOB session_key;
2405 DATA_BLOB crypt_secret, secret;
2408 NTSTATUS status = NT_STATUS_OK;
2410 struct timeval now = timeval_current();
2411 NTTIME nt_now = timeval_to_nttime(&now);
2413 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2415 secret_state = h->data;
2417 msg = ldb_msg_new(mem_ctx);
2419 return NT_STATUS_NO_MEMORY;
2422 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
2424 return NT_STATUS_NO_MEMORY;
2426 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2427 if (!NT_STATUS_IS_OK(status)) {
2431 if (r->in.old_val) {
2433 crypt_secret.data = r->in.old_val->data;
2434 crypt_secret.length = r->in.old_val->size;
2436 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2437 if (!NT_STATUS_IS_OK(status)) {
2441 val.data = secret.data;
2442 val.length = secret.length;
2445 if (samdb_msg_add_value(secret_state->sam_ldb,
2446 mem_ctx, msg, "priorValue", &val) != 0) {
2447 return NT_STATUS_NO_MEMORY;
2450 /* set old value mtime */
2451 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2452 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
2453 return NT_STATUS_NO_MEMORY;
2456 if (!r->in.new_val) {
2457 /* This behaviour varies depending of if this is a local, or a global secret... */
2458 if (secret_state->global) {
2459 /* set old value mtime */
2460 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2461 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2462 return NT_STATUS_NO_MEMORY;
2465 if (samdb_msg_add_delete(secret_state->sam_ldb,
2466 mem_ctx, msg, "currentValue")) {
2467 return NT_STATUS_NO_MEMORY;
2469 if (samdb_msg_add_delete(secret_state->sam_ldb,
2470 mem_ctx, msg, "lastSetTime")) {
2471 return NT_STATUS_NO_MEMORY;
2477 if (r->in.new_val) {
2479 crypt_secret.data = r->in.new_val->data;
2480 crypt_secret.length = r->in.new_val->size;
2482 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2483 if (!NT_STATUS_IS_OK(status)) {
2487 val.data = secret.data;
2488 val.length = secret.length;
2491 if (samdb_msg_add_value(secret_state->sam_ldb,
2492 mem_ctx, msg, "currentValue", &val) != 0) {
2493 return NT_STATUS_NO_MEMORY;
2496 /* set new value mtime */
2497 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2498 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2499 return NT_STATUS_NO_MEMORY;
2502 /* If the old value is not set, then migrate the
2503 * current value to the old value */
2504 if (!r->in.old_val) {
2505 const struct ldb_val *new_val;
2506 NTTIME last_set_time;
2507 struct ldb_message **res;
2508 const char *attrs[] = {
2514 /* search for the secret record */
2515 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
2516 secret_state->secret_dn, &res, attrs);
2518 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2522 DEBUG(0,("Found %d records matching dn=%s\n", ret,
2523 ldb_dn_get_linearized(secret_state->secret_dn)));
2524 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2527 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2528 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2532 if (samdb_msg_add_value(secret_state->sam_ldb,
2533 mem_ctx, msg, "priorValue",
2535 return NT_STATUS_NO_MEMORY;
2539 /* set new value mtime */
2540 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2541 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2542 mem_ctx, msg, "priorSetTime", last_set_time) != 0) {
2543 return NT_STATUS_NO_MEMORY;
2549 /* modify the samdb record */
2550 ret = samdb_replace(secret_state->sam_ldb, mem_ctx, msg);
2552 /* we really need samdb.c to return NTSTATUS */
2553 return NT_STATUS_UNSUCCESSFUL;
2556 return NT_STATUS_OK;
2563 static NTSTATUS lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2564 struct lsa_QuerySecret *r)
2566 struct dcesrv_handle *h;
2567 struct lsa_secret_state *secret_state;
2568 struct ldb_message *msg;
2569 DATA_BLOB session_key;
2570 DATA_BLOB crypt_secret, secret;
2572 struct ldb_message **res;
2573 const char *attrs[] = {
2583 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2585 secret_state = h->data;
2587 /* pull all the user attributes */
2588 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2589 secret_state->secret_dn, &res, attrs);
2591 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2595 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2596 if (!NT_STATUS_IS_OK(nt_status)) {
2600 if (r->in.old_val) {
2601 const struct ldb_val *prior_val;
2602 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2603 if (!r->out.old_val) {
2604 return NT_STATUS_NO_MEMORY;
2606 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
2608 if (prior_val && prior_val->length) {
2609 secret.data = prior_val->data;
2610 secret.length = prior_val->length;
2613 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2614 if (!crypt_secret.length) {
2615 return NT_STATUS_NO_MEMORY;
2617 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2618 if (!r->out.old_val->buf) {
2619 return NT_STATUS_NO_MEMORY;
2621 r->out.old_val->buf->size = crypt_secret.length;
2622 r->out.old_val->buf->length = crypt_secret.length;
2623 r->out.old_val->buf->data = crypt_secret.data;
2627 if (r->in.old_mtime) {
2628 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2629 if (!r->out.old_mtime) {
2630 return NT_STATUS_NO_MEMORY;
2632 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
2635 if (r->in.new_val) {
2636 const struct ldb_val *new_val;
2637 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2638 if (!r->out.new_val) {
2639 return NT_STATUS_NO_MEMORY;
2642 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2644 if (new_val && new_val->length) {
2645 secret.data = new_val->data;
2646 secret.length = new_val->length;
2649 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2650 if (!crypt_secret.length) {
2651 return NT_STATUS_NO_MEMORY;
2653 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2654 if (!r->out.new_val->buf) {
2655 return NT_STATUS_NO_MEMORY;
2657 r->out.new_val->buf->length = crypt_secret.length;
2658 r->out.new_val->buf->size = crypt_secret.length;
2659 r->out.new_val->buf->data = crypt_secret.data;
2663 if (r->in.new_mtime) {
2664 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2665 if (!r->out.new_mtime) {
2666 return NT_STATUS_NO_MEMORY;
2668 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2671 return NT_STATUS_OK;
2678 static NTSTATUS lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
2679 TALLOC_CTX *mem_ctx,
2680 struct lsa_LookupPrivValue *r)
2682 struct dcesrv_handle *h;
2683 struct lsa_policy_state *state;
2686 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2690 id = sec_privilege_id(r->in.name->string);
2692 return NT_STATUS_NO_SUCH_PRIVILEGE;
2695 r->out.luid->low = id;
2696 r->out.luid->high = 0;
2698 return NT_STATUS_OK;
2705 static NTSTATUS lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
2706 TALLOC_CTX *mem_ctx,
2707 struct lsa_LookupPrivName *r)
2709 struct dcesrv_handle *h;
2710 struct lsa_policy_state *state;
2711 const char *privname;
2713 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2717 if (r->in.luid->high != 0) {
2718 return NT_STATUS_NO_SUCH_PRIVILEGE;
2721 privname = sec_privilege_name(r->in.luid->low);
2722 if (privname == NULL) {
2723 return NT_STATUS_NO_SUCH_PRIVILEGE;
2726 r->out.name = talloc(mem_ctx, struct lsa_StringLarge);
2727 if (r->out.name == NULL) {
2728 return NT_STATUS_NO_MEMORY;
2730 r->out.name->string = privname;
2732 return NT_STATUS_OK;
2737 lsa_LookupPrivDisplayName
2739 static NTSTATUS lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
2740 TALLOC_CTX *mem_ctx,
2741 struct lsa_LookupPrivDisplayName *r)
2743 struct dcesrv_handle *h;
2744 struct lsa_policy_state *state;
2747 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2751 id = sec_privilege_id(r->in.name->string);
2753 return NT_STATUS_NO_SUCH_PRIVILEGE;
2756 r->out.disp_name = talloc(mem_ctx, struct lsa_StringLarge);
2757 if (r->out.disp_name == NULL) {
2758 return NT_STATUS_NO_MEMORY;
2761 r->out.disp_name->string = sec_privilege_display_name(id, r->in.language_id);
2762 if (r->out.disp_name->string == NULL) {
2763 return NT_STATUS_INTERNAL_ERROR;
2766 return NT_STATUS_OK;
2773 static NTSTATUS lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2774 struct lsa_DeleteObject *r)
2776 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2781 lsa_EnumAccountsWithUserRight
2783 static NTSTATUS lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
2784 TALLOC_CTX *mem_ctx,
2785 struct lsa_EnumAccountsWithUserRight *r)
2787 struct dcesrv_handle *h;
2788 struct lsa_policy_state *state;
2790 struct ldb_message **res;
2791 const char * const attrs[] = { "objectSid", NULL};
2792 const char *privname;
2794 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2798 if (r->in.name == NULL) {
2799 return NT_STATUS_NO_SUCH_PRIVILEGE;
2802 privname = r->in.name->string;
2803 if (sec_privilege_id(privname) == -1) {
2804 return NT_STATUS_NO_SUCH_PRIVILEGE;
2807 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
2808 "privilege=%s", privname);
2810 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2813 return NT_STATUS_NO_MORE_ENTRIES;
2816 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2817 if (r->out.sids->sids == NULL) {
2818 return NT_STATUS_NO_MEMORY;
2820 for (i=0;i<ret;i++) {
2821 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2822 res[i], "objectSid");
2823 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2825 r->out.sids->num_sids = ret;
2827 return NT_STATUS_OK;
2832 lsa_AddAccountRights
2834 static NTSTATUS lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
2835 TALLOC_CTX *mem_ctx,
2836 struct lsa_AddAccountRights *r)
2838 struct dcesrv_handle *h;
2839 struct lsa_policy_state *state;
2841 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2845 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2847 r->in.sid, r->in.rights);
2852 lsa_RemoveAccountRights
2854 static NTSTATUS lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
2855 TALLOC_CTX *mem_ctx,
2856 struct lsa_RemoveAccountRights *r)
2858 struct dcesrv_handle *h;
2859 struct lsa_policy_state *state;
2861 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2865 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2866 LDB_FLAG_MOD_DELETE,
2867 r->in.sid, r->in.rights);
2872 lsa_StorePrivateData
2874 static NTSTATUS lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2875 struct lsa_StorePrivateData *r)
2877 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2882 lsa_RetrievePrivateData
2884 static NTSTATUS lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2885 struct lsa_RetrievePrivateData *r)
2887 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2894 static NTSTATUS lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2895 struct lsa_GetUserName *r)
2897 NTSTATUS status = NT_STATUS_OK;
2898 const char *account_name;
2899 const char *authority_name;
2900 struct lsa_String *_account_name;
2901 struct lsa_StringPointer *_authority_name = NULL;
2903 /* this is what w2k3 does */
2904 r->out.account_name = r->in.account_name;
2905 r->out.authority_name = r->in.authority_name;
2907 if (r->in.account_name && r->in.account_name->string) {
2908 return NT_STATUS_INVALID_PARAMETER;
2911 if (r->in.authority_name &&
2912 r->in.authority_name->string &&
2913 r->in.authority_name->string->string) {
2914 return NT_STATUS_INVALID_PARAMETER;
2917 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
2918 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
2920 _account_name = talloc(mem_ctx, struct lsa_String);
2921 NT_STATUS_HAVE_NO_MEMORY(_account_name);
2922 _account_name->string = account_name;
2924 if (r->in.authority_name) {
2925 _authority_name = talloc(mem_ctx, struct lsa_StringPointer);
2926 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
2927 _authority_name->string = talloc(mem_ctx, struct lsa_String);
2928 NT_STATUS_HAVE_NO_MEMORY(_authority_name->string);
2929 _authority_name->string->string = authority_name;
2932 r->out.account_name = _account_name;
2933 r->out.authority_name = _authority_name;
2941 static NTSTATUS lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
2942 TALLOC_CTX *mem_ctx,
2943 struct lsa_SetInfoPolicy2 *r)
2945 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2949 lsa_QueryDomainInformationPolicy
2951 static NTSTATUS lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2952 TALLOC_CTX *mem_ctx,
2953 struct lsa_QueryDomainInformationPolicy *r)
2955 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2959 lsa_SetDomInfoPolicy
2961 static NTSTATUS lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2962 TALLOC_CTX *mem_ctx,
2963 struct lsa_SetDomainInformationPolicy *r)
2965 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2971 static NTSTATUS lsa_TestCall(struct dcesrv_call_state *dce_call,
2972 TALLOC_CTX *mem_ctx,
2973 struct lsa_TestCall *r)
2975 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2979 lookup a SID for 1 name
2981 static NTSTATUS lsa_lookup_name(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
2982 const char *name, struct dom_sid **sid, uint32_t *atype)
2985 struct ldb_message **res;
2986 const char * const attrs[] = { "objectSid", "sAMAccountType", NULL};
2989 p = strchr_m(name, '\\');
2991 /* TODO: properly parse the domain prefix here, and use it to
2996 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs, "sAMAccountName=%s", ldb_binary_encode_string(mem_ctx, name));
2998 *sid = samdb_result_dom_sid(mem_ctx, res[0], "objectSid");
3000 return NT_STATUS_INVALID_SID;
3003 *atype = samdb_result_uint(res[0], "sAMAccountType", 0);
3005 return NT_STATUS_OK;
3008 /* need to add a call into sidmap to check for a allocated sid */
3010 return NT_STATUS_INVALID_SID;
3017 static NTSTATUS lsa_LookupNames3(struct dcesrv_call_state *dce_call,
3018 TALLOC_CTX *mem_ctx,
3019 struct lsa_LookupNames3 *r)
3021 struct lsa_policy_state *policy_state;
3022 struct dcesrv_handle *policy_handle;
3024 NTSTATUS status = NT_STATUS_OK;
3026 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
3028 policy_state = policy_handle->data;
3030 r->out.domains = NULL;
3032 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
3033 if (r->out.domains == NULL) {
3034 return NT_STATUS_NO_MEMORY;
3037 r->out.sids = talloc_zero(mem_ctx, struct lsa_TransSidArray3);
3038 if (r->out.sids == NULL) {
3039 return NT_STATUS_NO_MEMORY;
3044 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid3,
3046 if (r->out.sids->sids == NULL) {
3047 return NT_STATUS_NO_MEMORY;
3050 for (i=0;i<r->in.num_names;i++) {
3051 const char *name = r->in.names[i].string;
3052 struct dom_sid *sid;
3053 uint32_t atype, rtype, sid_index;
3056 r->out.sids->count++;
3059 r->out.sids->sids[i].sid_type = SID_NAME_UNKNOWN;
3060 r->out.sids->sids[i].sid = NULL;
3061 r->out.sids->sids[i].sid_index = 0xFFFFFFFF;
3062 r->out.sids->sids[i].unknown = 0;
3064 status2 = lsa_lookup_name(policy_state, mem_ctx, name, &sid, &atype);
3065 if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
3066 status = STATUS_SOME_UNMAPPED;
3070 rtype = samdb_atype_map(atype);
3071 if (rtype == SID_NAME_UNKNOWN) {
3072 status = STATUS_SOME_UNMAPPED;
3076 status2 = lsa_authority_list(policy_state, mem_ctx, sid, r->out.domains, &sid_index);
3077 if (!NT_STATUS_IS_OK(status2)) {
3081 r->out.sids->sids[i].sid_type = rtype;
3082 r->out.sids->sids[i].sid = sid;
3083 r->out.sids->sids[i].sid_index = sid_index;
3084 r->out.sids->sids[i].unknown = 0;
3093 Identical to LookupNames3, but doesn't take a policy handle
3096 static NTSTATUS lsa_LookupNames4(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3097 struct lsa_LookupNames4 *r)
3099 struct lsa_LookupNames3 r2;
3100 struct lsa_OpenPolicy2 pol;
3102 struct dcesrv_handle *h;
3104 /* No policy handle on the wire, so make one up here */
3105 r2.in.handle = talloc(mem_ctx, struct policy_handle);
3106 if (!r2.in.handle) {
3107 return NT_STATUS_NO_MEMORY;
3110 pol.out.handle = r2.in.handle;
3111 pol.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3113 pol.in.system_name = NULL;
3114 status = lsa_OpenPolicy2(dce_call, mem_ctx, &pol);
3115 if (!NT_STATUS_IS_OK(status)) {
3119 /* ensure this handle goes away at the end of this call */
3120 DCESRV_PULL_HANDLE(h, r2.in.handle, LSA_HANDLE_POLICY);
3121 talloc_steal(mem_ctx, h);
3123 r2.in.num_names = r->in.num_names;
3124 r2.in.names = r->in.names;
3125 r2.in.sids = r->in.sids;
3126 r2.in.count = r->in.count;
3127 r2.in.unknown1 = r->in.unknown1;
3128 r2.in.unknown2 = r->in.unknown2;
3129 r2.out.domains = r->out.domains;
3130 r2.out.sids = r->out.sids;
3131 r2.out.count = r->out.count;
3133 status = lsa_LookupNames3(dce_call, mem_ctx, &r2);
3134 if (dce_call->fault_code != 0) {
3138 r->out.domains = r2.out.domains;
3139 r->out.sids = r2.out.sids;
3140 r->out.count = r2.out.count;
3147 static NTSTATUS lsa_LookupNames2(struct dcesrv_call_state *dce_call,
3148 TALLOC_CTX *mem_ctx,
3149 struct lsa_LookupNames2 *r)
3151 struct lsa_policy_state *state;
3152 struct dcesrv_handle *h;
3154 NTSTATUS status = NT_STATUS_OK;
3156 r->out.domains = NULL;
3158 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3162 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
3163 if (r->out.domains == NULL) {
3164 return NT_STATUS_NO_MEMORY;
3167 r->out.sids = talloc_zero(mem_ctx, struct lsa_TransSidArray2);
3168 if (r->out.sids == NULL) {
3169 return NT_STATUS_NO_MEMORY;
3174 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid2,
3176 if (r->out.sids->sids == NULL) {
3177 return NT_STATUS_NO_MEMORY;
3180 for (i=0;i<r->in.num_names;i++) {
3181 const char *name = r->in.names[i].string;
3182 struct dom_sid *sid;
3183 uint32_t atype, rtype, sid_index;
3186 r->out.sids->count++;
3189 r->out.sids->sids[i].sid_type = SID_NAME_UNKNOWN;
3190 r->out.sids->sids[i].rid = 0xFFFFFFFF;
3191 r->out.sids->sids[i].sid_index = 0xFFFFFFFF;
3192 r->out.sids->sids[i].unknown = 0;
3194 status2 = lsa_lookup_name(state, mem_ctx, name, &sid, &atype);
3195 if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
3196 status = STATUS_SOME_UNMAPPED;
3200 rtype = samdb_atype_map(atype);
3201 if (rtype == SID_NAME_UNKNOWN) {
3202 status = STATUS_SOME_UNMAPPED;
3206 status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
3207 if (!NT_STATUS_IS_OK(status2)) {
3211 r->out.sids->sids[i].sid_type = rtype;
3212 r->out.sids->sids[i].rid = sid->sub_auths[sid->num_auths-1];
3213 r->out.sids->sids[i].sid_index = sid_index;
3214 r->out.sids->sids[i].unknown = 0;
3223 static NTSTATUS lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3224 struct lsa_LookupNames *r)
3226 struct lsa_LookupNames2 r2;
3230 r2.in.handle = r->in.handle;
3231 r2.in.num_names = r->in.num_names;
3232 r2.in.names = r->in.names;
3234 r2.in.level = r->in.level;
3235 r2.in.count = r->in.count;
3238 r2.out.count = r->out.count;
3240 status = lsa_LookupNames2(dce_call, mem_ctx, &r2);
3241 if (dce_call->fault_code != 0) {
3245 r->out.domains = r2.out.domains;
3246 r->out.sids = talloc(mem_ctx, struct lsa_TransSidArray);
3247 if (r->out.sids == NULL) {
3248 return NT_STATUS_NO_MEMORY;
3250 r->out.sids->count = r2.out.sids->count;
3251 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid,
3252 r->out.sids->count);
3253 if (r->out.sids->sids == NULL) {
3254 return NT_STATUS_NO_MEMORY;
3256 for (i=0;i<r->out.sids->count;i++) {
3257 r->out.sids->sids[i].sid_type = r2.out.sids->sids[i].sid_type;
3258 r->out.sids->sids[i].rid = r2.out.sids->sids[i].rid;
3259 r->out.sids->sids[i].sid_index = r2.out.sids->sids[i].sid_index;
3268 static NTSTATUS lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3269 struct lsa_CREDRWRITE *r)
3271 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3278 static NTSTATUS lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3279 struct lsa_CREDRREAD *r)
3281 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3288 static NTSTATUS lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3289 struct lsa_CREDRENUMERATE *r)
3291 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3296 lsa_CREDRWRITEDOMAINCREDENTIALS
3298 static NTSTATUS lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3299 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3301 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3306 lsa_CREDRREADDOMAINCREDENTIALS
3308 static NTSTATUS lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3309 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3311 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3318 static NTSTATUS lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3319 struct lsa_CREDRDELETE *r)
3321 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3326 lsa_CREDRGETTARGETINFO
3328 static NTSTATUS lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3329 struct lsa_CREDRGETTARGETINFO *r)
3331 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3336 lsa_CREDRPROFILELOADED
3338 static NTSTATUS lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3339 struct lsa_CREDRPROFILELOADED *r)
3341 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3346 lsa_CREDRGETSESSIONTYPES
3348 static NTSTATUS lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3349 struct lsa_CREDRGETSESSIONTYPES *r)
3351 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3356 lsa_LSARREGISTERAUDITEVENT
3358 static NTSTATUS lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3359 struct lsa_LSARREGISTERAUDITEVENT *r)
3361 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3366 lsa_LSARGENAUDITEVENT
3368 static NTSTATUS lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3369 struct lsa_LSARGENAUDITEVENT *r)
3371 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3376 lsa_LSARUNREGISTERAUDITEVENT
3378 static NTSTATUS lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3379 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3381 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3386 lsa_LSARQUERYFORESTTRUSTINFORMATION
3388 static NTSTATUS lsa_LSARQUERYFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3389 struct lsa_LSARQUERYFORESTTRUSTINFORMATION *r)
3391 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3396 lsa_LSARSETFORESTTRUSTINFORMATION
3398 static NTSTATUS lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3399 struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
3401 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3408 static NTSTATUS lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3409 struct lsa_CREDRRENAME *r)
3411 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3417 lsa_LSAROPENPOLICYSCE
3419 static NTSTATUS lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3420 struct lsa_LSAROPENPOLICYSCE *r)
3422 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3427 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
3429 static NTSTATUS lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3430 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
3432 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3437 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
3439 static NTSTATUS lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3440 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
3442 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3447 lsa_LSARADTREPORTSECURITYEVENT
3449 static NTSTATUS lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3450 struct lsa_LSARADTREPORTSECURITYEVENT *r)
3452 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3456 /* include the generated boilerplate */
3457 #include "librpc/gen_ndr/ndr_lsa_s.c"
3461 /*****************************************
3462 NOTE! The remaining calls below were
3463 removed in w2k3, so the DCESRV_FAULT()
3464 replies are the correct implementation. Do
3465 not try and fill these in with anything else
3466 ******************************************/
3469 dssetup_DsRoleDnsNameToFlatName
3471 static WERROR dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3472 struct dssetup_DsRoleDnsNameToFlatName *r)
3474 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3479 dssetup_DsRoleDcAsDc
3481 static WERROR dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3482 struct dssetup_DsRoleDcAsDc *r)
3484 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3489 dssetup_DsRoleDcAsReplica
3491 static WERROR dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3492 struct dssetup_DsRoleDcAsReplica *r)
3494 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3499 dssetup_DsRoleDemoteDc
3501 static WERROR dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3502 struct dssetup_DsRoleDemoteDc *r)
3504 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3509 dssetup_DsRoleGetDcOperationProgress
3511 static WERROR dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3512 struct dssetup_DsRoleGetDcOperationProgress *r)
3514 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3519 dssetup_DsRoleGetDcOperationResults
3521 static WERROR dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3522 struct dssetup_DsRoleGetDcOperationResults *r)
3524 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3529 dssetup_DsRoleCancel
3531 static WERROR dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3532 struct dssetup_DsRoleCancel *r)
3534 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3539 dssetup_DsRoleServerSaveStateForUpgrade
3541 static WERROR dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3542 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
3544 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3549 dssetup_DsRoleUpgradeDownlevelServer
3551 static WERROR dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3552 struct dssetup_DsRoleUpgradeDownlevelServer *r)
3554 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3559 dssetup_DsRoleAbortDownlevelServerUpgrade
3561 static WERROR dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3562 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
3564 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3568 /* include the generated boilerplate */
3569 #include "librpc/gen_ndr/ndr_dssetup_s.c"
3571 NTSTATUS dcerpc_server_lsa_init(void)
3575 ret = dcerpc_server_dssetup_init();
3576 if (!NT_STATUS_IS_OK(ret)) {
3579 ret = dcerpc_server_lsarpc_init();
3580 if (!NT_STATUS_IS_OK(ret)) {