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[] = {
282 struct ldb_result *ref_res;
283 const char *ref_attrs[] = {
290 state = talloc(mem_ctx, struct lsa_policy_state);
292 return NT_STATUS_NO_MEMORY;
295 /* make sure the sam database is accessible */
296 state->sam_ldb = samdb_connect(state, dce_call->conn->auth_state.session_info);
297 if (state->sam_ldb == NULL) {
298 return NT_STATUS_INVALID_SYSTEM_SERVICE;
301 partitions_basedn = samdb_partitions_dn(state->sam_ldb, mem_ctx);
303 state->sidmap = sidmap_open(state);
304 if (state->sidmap == NULL) {
305 return NT_STATUS_INVALID_SYSTEM_SERVICE;
308 /* work out the domain_dn - useful for so many calls its worth
310 state->domain_dn = samdb_base_dn(state->sam_ldb);
311 if (!state->domain_dn) {
312 return NT_STATUS_NO_MEMORY;
315 ret = ldb_search(state->sam_ldb, state->domain_dn, LDB_SCOPE_BASE, NULL, dom_attrs, &dom_res);
317 if (ret != LDB_SUCCESS) {
318 return NT_STATUS_INVALID_SYSTEM_SERVICE;
320 talloc_steal(state, dom_res);
321 if (dom_res->count != 1) {
322 return NT_STATUS_NO_SUCH_DOMAIN;
325 state->domain_sid = samdb_result_dom_sid(state, dom_res->msgs[0], "objectSid");
326 if (!state->domain_sid) {
327 return NT_STATUS_NO_SUCH_DOMAIN;
330 state->domain_guid = samdb_result_guid(dom_res->msgs[0], "objectGUID");
331 if (!state->domain_sid) {
332 return NT_STATUS_NO_SUCH_DOMAIN;
335 state->mixed_domain = ldb_msg_find_attr_as_uint(dom_res->msgs[0], "nTMixedDomain", 0);
337 talloc_free(dom_res);
339 ret = ldb_search_exp_fmt(state->sam_ldb, state, &ref_res,
340 partitions_basedn, LDB_SCOPE_SUBTREE, ref_attrs,
341 "(&(objectclass=crossRef)(ncName=%s))",
342 ldb_dn_get_linearized(state->domain_dn));
344 if (ret != LDB_SUCCESS) {
345 talloc_free(ref_res);
346 return NT_STATUS_INVALID_SYSTEM_SERVICE;
348 if (ref_res->count != 1) {
349 talloc_free(ref_res);
350 return NT_STATUS_NO_SUCH_DOMAIN;
353 state->domain_name = ldb_msg_find_attr_as_string(ref_res->msgs[0], "nETBIOSName", NULL);
354 if (!state->domain_name) {
355 talloc_free(ref_res);
356 return NT_STATUS_NO_SUCH_DOMAIN;
358 talloc_steal(state, state->domain_name);
360 state->domain_dns = ldb_msg_find_attr_as_string(ref_res->msgs[0], "dnsRoot", NULL);
361 if (!state->domain_dns) {
362 talloc_free(ref_res);
363 return NT_STATUS_NO_SUCH_DOMAIN;
365 talloc_steal(state, state->domain_dns);
367 talloc_free(ref_res);
369 /* work out the builtin_dn - useful for so many calls its worth
371 state->builtin_dn = samdb_search_dn(state->sam_ldb, state, state->domain_dn, "(objectClass=builtinDomain)");
372 if (!state->builtin_dn) {
373 return NT_STATUS_NO_SUCH_DOMAIN;
376 /* work out the system_dn - useful for so many calls its worth
378 state->system_dn = samdb_search_dn(state->sam_ldb, state,
379 state->domain_dn, "(&(objectClass=container)(cn=System))");
380 if (!state->system_dn) {
381 return NT_STATUS_NO_SUCH_DOMAIN;
384 state->builtin_sid = dom_sid_parse_talloc(state, SID_BUILTIN);
385 if (!state->builtin_sid) {
386 return NT_STATUS_NO_SUCH_DOMAIN;
395 dssetup_DsRoleGetPrimaryDomainInformation
397 This is not an LSA call, but is the only call left on the DSSETUP
398 pipe (after the pipe was truncated), and needs lsa_get_policy_state
400 static WERROR dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state *dce_call,
402 struct dssetup_DsRoleGetPrimaryDomainInformation *r)
404 union dssetup_DsRoleInfo *info;
406 info = talloc(mem_ctx, union dssetup_DsRoleInfo);
407 W_ERROR_HAVE_NO_MEMORY(info);
409 switch (r->in.level) {
410 case DS_ROLE_BASIC_INFORMATION:
412 enum dssetup_DsRole role = DS_ROLE_STANDALONE_SERVER;
414 const char *domain = NULL;
415 const char *dns_domain = NULL;
416 const char *forest = NULL;
417 struct GUID domain_guid;
418 struct lsa_policy_state *state;
420 NTSTATUS status = lsa_get_policy_state(dce_call, mem_ctx, &state);
421 if (!NT_STATUS_IS_OK(status)) {
422 return ntstatus_to_werror(status);
425 ZERO_STRUCT(domain_guid);
427 switch (lp_server_role()) {
428 case ROLE_STANDALONE:
429 role = DS_ROLE_STANDALONE_SERVER;
431 case ROLE_DOMAIN_MEMBER:
432 role = DS_ROLE_MEMBER_SERVER;
434 case ROLE_DOMAIN_BDC:
435 role = DS_ROLE_BACKUP_DC;
437 case ROLE_DOMAIN_PDC:
438 role = DS_ROLE_PRIMARY_DC;
442 switch (lp_server_role()) {
443 case ROLE_STANDALONE:
444 domain = talloc_strdup(mem_ctx, lp_workgroup());
445 W_ERROR_HAVE_NO_MEMORY(domain);
447 case ROLE_DOMAIN_MEMBER:
448 domain = talloc_strdup(mem_ctx, lp_workgroup());
449 W_ERROR_HAVE_NO_MEMORY(domain);
450 /* TODO: what is with dns_domain and forest and guid? */
452 case ROLE_DOMAIN_BDC:
453 case ROLE_DOMAIN_PDC:
454 flags = DS_ROLE_PRIMARY_DS_RUNNING;
456 if (state->mixed_domain == 1) {
457 flags |= DS_ROLE_PRIMARY_DS_MIXED_MODE;
460 domain = state->domain_name;
461 dns_domain = state->domain_dns;
462 forest = state->domain_dns;
464 domain_guid = state->domain_guid;
465 flags |= DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT;
469 info->basic.role = role;
470 info->basic.flags = flags;
471 info->basic.domain = domain;
472 info->basic.dns_domain = dns_domain;
473 info->basic.forest = forest;
474 info->basic.domain_guid = domain_guid;
479 case DS_ROLE_UPGRADE_STATUS:
481 info->upgrade.upgrading = DS_ROLE_NOT_UPGRADING;
482 info->upgrade.previous_role = DS_ROLE_PREVIOUS_UNKNOWN;
487 case DS_ROLE_OP_STATUS:
489 info->opstatus.status = DS_ROLE_OP_IDLE;
495 return WERR_INVALID_PARAM;
498 return WERR_INVALID_PARAM;
504 static NTSTATUS lsa_OpenPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
505 struct lsa_OpenPolicy2 *r)
508 struct lsa_policy_state *state;
509 struct dcesrv_handle *handle;
511 ZERO_STRUCTP(r->out.handle);
513 status = lsa_get_policy_state(dce_call, mem_ctx, &state);
514 if (!NT_STATUS_IS_OK(status)) {
518 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_POLICY);
520 return NT_STATUS_NO_MEMORY;
523 handle->data = talloc_steal(handle, state);
525 state->access_mask = r->in.access_mask;
526 state->handle = handle;
527 *r->out.handle = handle->wire_handle;
529 /* note that we have completely ignored the attr element of
530 the OpenPolicy. As far as I can tell, this is what w2k3
538 a wrapper around lsa_OpenPolicy2
540 static NTSTATUS lsa_OpenPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
541 struct lsa_OpenPolicy *r)
543 struct lsa_OpenPolicy2 r2;
545 r2.in.system_name = NULL;
546 r2.in.attr = r->in.attr;
547 r2.in.access_mask = r->in.access_mask;
548 r2.out.handle = r->out.handle;
550 return lsa_OpenPolicy2(dce_call, mem_ctx, &r2);
557 fill in the AccountDomain info
559 static NTSTATUS lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
560 struct lsa_DomainInfo *info)
562 info->name.string = state->domain_name;
563 info->sid = state->domain_sid;
569 fill in the DNS domain info
571 static NTSTATUS lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
572 struct lsa_DnsDomainInfo *info)
574 info->name.string = state->domain_name;
575 info->sid = state->domain_sid;
576 info->dns_domain.string = state->domain_dns;
577 info->dns_forest.string = state->domain_dns;
578 info->domain_guid = state->domain_guid;
586 static NTSTATUS lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
587 struct lsa_QueryInfoPolicy2 *r)
589 struct lsa_policy_state *state;
590 struct dcesrv_handle *h;
594 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
598 r->out.info = talloc(mem_ctx, union lsa_PolicyInformation);
600 return NT_STATUS_NO_MEMORY;
603 ZERO_STRUCTP(r->out.info);
605 switch (r->in.level) {
606 case LSA_POLICY_INFO_DOMAIN:
607 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
608 return lsa_info_AccountDomain(state, mem_ctx, &r->out.info->account_domain);
610 case LSA_POLICY_INFO_DNS:
611 return lsa_info_DNS(state, mem_ctx, &r->out.info->dns);
614 return NT_STATUS_INVALID_INFO_CLASS;
620 static NTSTATUS lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
621 struct lsa_QueryInfoPolicy *r)
623 struct lsa_QueryInfoPolicy2 r2;
626 r2.in.handle = r->in.handle;
627 r2.in.level = r->in.level;
629 status = lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
631 r->out.info = r2.out.info;
639 static NTSTATUS lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
640 struct lsa_SetInfoPolicy *r)
642 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
649 static NTSTATUS lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
650 struct lsa_ClearAuditLog *r)
652 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
659 static NTSTATUS lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
660 struct lsa_CreateAccount *r)
662 struct lsa_account_state *astate;
664 struct lsa_policy_state *state;
665 struct dcesrv_handle *h, *ah;
667 ZERO_STRUCTP(r->out.acct_handle);
669 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
673 astate = talloc(dce_call->conn, struct lsa_account_state);
674 if (astate == NULL) {
675 return NT_STATUS_NO_MEMORY;
678 astate->account_sid = dom_sid_dup(astate, r->in.sid);
679 if (astate->account_sid == NULL) {
681 return NT_STATUS_NO_MEMORY;
684 astate->policy = talloc_reference(astate, state);
685 astate->access_mask = r->in.access_mask;
687 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
690 return NT_STATUS_NO_MEMORY;
693 ah->data = talloc_steal(ah, astate);
695 *r->out.acct_handle = ah->wire_handle;
704 static NTSTATUS lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
705 struct lsa_EnumAccounts *r)
707 struct dcesrv_handle *h;
708 struct lsa_policy_state *state;
710 struct ldb_message **res;
711 const char * const attrs[] = { "objectSid", NULL};
714 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
718 /* NOTE: This call must only return accounts that have at least
721 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
722 "(&(objectSid=*)(privilege=*))");
724 return NT_STATUS_NO_SUCH_USER;
727 if (*r->in.resume_handle >= ret) {
728 return NT_STATUS_NO_MORE_ENTRIES;
731 count = ret - *r->in.resume_handle;
732 if (count > r->in.num_entries) {
733 count = r->in.num_entries;
737 return NT_STATUS_NO_MORE_ENTRIES;
740 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, count);
741 if (r->out.sids->sids == NULL) {
742 return NT_STATUS_NO_MEMORY;
745 for (i=0;i<count;i++) {
746 r->out.sids->sids[i].sid =
747 samdb_result_dom_sid(r->out.sids->sids,
748 res[i + *r->in.resume_handle],
750 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
753 r->out.sids->num_sids = count;
754 *r->out.resume_handle = count + *r->in.resume_handle;
762 lsa_CreateTrustedDomainEx2
764 static NTSTATUS lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
766 struct lsa_CreateTrustedDomainEx2 *r)
768 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
772 lsa_CreateTrustedDomainEx
774 static NTSTATUS lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
776 struct lsa_CreateTrustedDomainEx *r)
778 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
782 lsa_CreateTrustedDomain
784 static NTSTATUS lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
785 struct lsa_CreateTrustedDomain *r)
787 struct dcesrv_handle *policy_handle;
788 struct lsa_policy_state *policy_state;
789 struct lsa_trusted_domain_state *trusted_domain_state;
790 struct dcesrv_handle *handle;
791 struct ldb_message **msgs, *msg;
792 const char *attrs[] = {
798 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
799 ZERO_STRUCTP(r->out.trustdom_handle);
801 policy_state = policy_handle->data;
803 if (!r->in.info->name.string) {
804 return NT_STATUS_INVALID_PARAMETER;
806 name = r->in.info->name.string;
808 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
809 if (!trusted_domain_state) {
810 return NT_STATUS_NO_MEMORY;
812 trusted_domain_state->policy = policy_state;
814 msg = ldb_msg_new(mem_ctx);
816 return NT_STATUS_NO_MEMORY;
819 /* search for the trusted_domain record */
820 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
821 mem_ctx, policy_state->system_dn, &msgs, attrs,
822 "(&(cn=%s)(objectclass=trustedDomain))",
823 ldb_binary_encode_string(mem_ctx, r->in.info->name.string));
825 return NT_STATUS_OBJECT_NAME_COLLISION;
828 if (ret < 0 || ret > 1) {
829 DEBUG(0,("Found %d records matching DN %s\n", ret,
830 ldb_dn_get_linearized(policy_state->system_dn)));
831 return NT_STATUS_INTERNAL_DB_CORRUPTION;
834 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
835 if ( ! ldb_dn_add_child_fmt(msg->dn, "sn=%s", r->in.info->name.string)) {
836 return NT_STATUS_NO_MEMORY;
839 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "cn", name);
840 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "flatname", name);
842 if (r->in.info->sid) {
843 const char *sid_string = dom_sid_string(mem_ctx, r->in.info->sid);
845 return NT_STATUS_NO_MEMORY;
848 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "securityIdentifier", sid_string);
851 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "objectClass", "trustedDomain");
853 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
855 /* create the trusted_domain */
856 ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg);
857 if (ret != LDB_SUCCESS) {
858 DEBUG(0,("Failed to create trusted_domain record %s: %s\n",
859 ldb_dn_get_linearized(msg->dn), ldb_errstring(trusted_domain_state->policy->sam_ldb)));
860 return NT_STATUS_INTERNAL_DB_CORRUPTION;
863 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
865 return NT_STATUS_NO_MEMORY;
868 handle->data = talloc_steal(handle, trusted_domain_state);
870 trusted_domain_state->access_mask = r->in.access_mask;
871 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
873 *r->out.trustdom_handle = handle->wire_handle;
879 lsa_OpenTrustedDomain
881 static NTSTATUS lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
882 struct lsa_OpenTrustedDomain *r)
884 struct dcesrv_handle *policy_handle;
886 struct lsa_policy_state *policy_state;
887 struct lsa_trusted_domain_state *trusted_domain_state;
888 struct dcesrv_handle *handle;
889 struct ldb_message **msgs;
890 const char *attrs[] = {
894 const char *sid_string;
897 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
898 ZERO_STRUCTP(r->out.trustdom_handle);
899 policy_state = policy_handle->data;
901 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
902 if (!trusted_domain_state) {
903 return NT_STATUS_NO_MEMORY;
905 trusted_domain_state->policy = policy_state;
907 sid_string = dom_sid_string(mem_ctx, r->in.sid);
909 return NT_STATUS_NO_MEMORY;
912 /* search for the trusted_domain record */
913 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
914 mem_ctx, policy_state->system_dn, &msgs, attrs,
915 "(&(securityIdentifier=%s)(objectclass=trustedDomain))",
918 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
922 DEBUG(0,("Found %d records matching DN %s\n", ret,
923 ldb_dn_get_linearized(policy_state->system_dn)));
924 return NT_STATUS_INTERNAL_DB_CORRUPTION;
927 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
929 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
931 return NT_STATUS_NO_MEMORY;
934 handle->data = talloc_steal(handle, trusted_domain_state);
936 trusted_domain_state->access_mask = r->in.access_mask;
937 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
939 *r->out.trustdom_handle = handle->wire_handle;
946 lsa_OpenTrustedDomainByName
948 static NTSTATUS lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
950 struct lsa_OpenTrustedDomainByName *r)
952 struct dcesrv_handle *policy_handle;
954 struct lsa_policy_state *policy_state;
955 struct lsa_trusted_domain_state *trusted_domain_state;
956 struct dcesrv_handle *handle;
957 struct ldb_message **msgs;
958 const char *attrs[] = {
964 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
965 ZERO_STRUCTP(r->out.trustdom_handle);
966 policy_state = policy_handle->data;
968 if (!r->in.name.string) {
969 return NT_STATUS_INVALID_PARAMETER;
972 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
973 if (!trusted_domain_state) {
974 return NT_STATUS_NO_MEMORY;
976 trusted_domain_state->policy = policy_state;
978 /* search for the trusted_domain record */
979 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
980 mem_ctx, policy_state->system_dn, &msgs, attrs,
981 "(&(flatname=%s)(objectclass=trustedDomain))",
982 ldb_binary_encode_string(mem_ctx, r->in.name.string));
984 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
988 DEBUG(0,("Found %d records matching DN %s\n", ret,
989 ldb_dn_get_linearized(policy_state->system_dn)));
990 return NT_STATUS_INTERNAL_DB_CORRUPTION;
993 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
995 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
997 return NT_STATUS_NO_MEMORY;
1000 handle->data = talloc_steal(handle, trusted_domain_state);
1002 trusted_domain_state->access_mask = r->in.access_mask;
1003 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1005 *r->out.trustdom_handle = handle->wire_handle;
1007 return NT_STATUS_OK;
1013 lsa_SetTrustedDomainInfo
1015 static NTSTATUS lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1016 struct lsa_SetTrustedDomainInfo *r)
1018 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1024 lsa_SetInfomrationTrustedDomain
1026 static NTSTATUS lsa_SetInformationTrustedDomain(struct dcesrv_call_state *dce_call,
1027 TALLOC_CTX *mem_ctx,
1028 struct lsa_SetInformationTrustedDomain *r)
1030 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1035 lsa_DeleteTrustedDomain
1037 static NTSTATUS lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1038 struct lsa_DeleteTrustedDomain *r)
1041 struct lsa_OpenTrustedDomain open;
1042 struct lsa_Delete delete;
1043 struct dcesrv_handle *h;
1045 open.in.handle = r->in.handle;
1046 open.in.sid = r->in.dom_sid;
1047 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1048 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1049 if (!open.out.trustdom_handle) {
1050 return NT_STATUS_NO_MEMORY;
1052 status = lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
1053 if (!NT_STATUS_IS_OK(status)) {
1057 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1058 talloc_steal(mem_ctx, h);
1060 delete.in.handle = open.out.trustdom_handle;
1061 status = lsa_Delete(dce_call, mem_ctx, &delete);
1062 if (!NT_STATUS_IS_OK(status)) {
1065 return NT_STATUS_OK;
1068 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx,
1069 struct ldb_message *msg,
1070 struct lsa_TrustDomainInfoInfoEx *info_ex)
1072 info_ex->domain_name.string
1073 = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
1074 info_ex->netbios_name.string
1075 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1077 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1078 info_ex->trust_direction
1079 = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
1081 = ldb_msg_find_attr_as_int(msg, "trustType", 0);
1082 info_ex->trust_attributes
1083 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);
1084 return NT_STATUS_OK;
1088 lsa_QueryTrustedDomainInfo
1090 static NTSTATUS lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1091 struct lsa_QueryTrustedDomainInfo *r)
1093 struct dcesrv_handle *h;
1094 struct lsa_trusted_domain_state *trusted_domain_state;
1095 struct ldb_message *msg;
1097 struct ldb_message **res;
1098 const char *attrs[] = {
1101 "securityIdentifier",
1108 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
1110 trusted_domain_state = h->data;
1112 /* pull all the user attributes */
1113 ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
1114 trusted_domain_state->trusted_domain_dn, &res, attrs);
1116 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1120 r->out.info = talloc(mem_ctx, union lsa_TrustedDomainInfo);
1122 return NT_STATUS_NO_MEMORY;
1124 switch (r->in.level) {
1125 case LSA_TRUSTED_DOMAIN_INFO_NAME:
1126 r->out.info->name.netbios_name.string
1127 = samdb_result_string(msg, "flatname", NULL);
1129 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1130 r->out.info->posix_offset.posix_offset
1131 = samdb_result_uint(msg, "posixOffset", 0);
1133 #if 0 /* Win2k3 doesn't implement this */
1134 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
1135 r->out.info->info_basic.netbios_name.string
1136 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1137 r->out.info->info_basic.sid
1138 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1141 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1142 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->info_ex);
1144 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1145 ZERO_STRUCT(r->out.info->full_info);
1146 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->full_info.info_ex);
1148 case LSA_TRUSTED_DOMAIN_INFO_INFO_ALL:
1149 ZERO_STRUCT(r->out.info->info_all);
1150 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->info_all.info_ex);
1152 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS_INFO:
1153 case LSA_TRUSTED_DOMAIN_INFO_11:
1154 /* oops, we don't want to return the info after all */
1155 talloc_free(r->out.info);
1157 return NT_STATUS_INVALID_PARAMETER;
1159 /* oops, we don't want to return the info after all */
1160 talloc_free(r->out.info);
1162 return NT_STATUS_INVALID_INFO_CLASS;
1165 return NT_STATUS_OK;
1170 lsa_QueryTrustedDomainInfoBySid
1172 static NTSTATUS lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1173 struct lsa_QueryTrustedDomainInfoBySid *r)
1176 struct lsa_OpenTrustedDomain open;
1177 struct lsa_QueryTrustedDomainInfo query;
1178 struct dcesrv_handle *h;
1179 open.in.handle = r->in.handle;
1180 open.in.sid = r->in.dom_sid;
1181 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1182 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1183 if (!open.out.trustdom_handle) {
1184 return NT_STATUS_NO_MEMORY;
1186 status = lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
1187 if (!NT_STATUS_IS_OK(status)) {
1191 /* Ensure this handle goes away at the end of this call */
1192 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1193 talloc_steal(mem_ctx, h);
1195 query.in.trustdom_handle = open.out.trustdom_handle;
1196 query.in.level = r->in.level;
1197 status = lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1198 if (!NT_STATUS_IS_OK(status)) {
1202 r->out.info = query.out.info;
1203 return NT_STATUS_OK;
1207 lsa_SetTrustedDomainInfoByName
1209 static NTSTATUS lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1210 TALLOC_CTX *mem_ctx,
1211 struct lsa_SetTrustedDomainInfoByName *r)
1213 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1217 lsa_QueryTrustedDomainInfoByName
1219 static NTSTATUS lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1220 TALLOC_CTX *mem_ctx,
1221 struct lsa_QueryTrustedDomainInfoByName *r)
1224 struct lsa_OpenTrustedDomainByName open;
1225 struct lsa_QueryTrustedDomainInfo query;
1226 struct dcesrv_handle *h;
1227 open.in.handle = r->in.handle;
1228 open.in.name = r->in.trusted_domain;
1229 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1230 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1231 if (!open.out.trustdom_handle) {
1232 return NT_STATUS_NO_MEMORY;
1234 status = lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &open);
1235 if (!NT_STATUS_IS_OK(status)) {
1239 /* Ensure this handle goes away at the end of this call */
1240 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1241 talloc_steal(mem_ctx, h);
1243 query.in.trustdom_handle = open.out.trustdom_handle;
1244 query.in.level = r->in.level;
1245 status = lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1246 if (!NT_STATUS_IS_OK(status)) {
1250 r->out.info = query.out.info;
1251 return NT_STATUS_OK;
1255 lsa_CloseTrustedDomainEx
1257 static NTSTATUS lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
1258 TALLOC_CTX *mem_ctx,
1259 struct lsa_CloseTrustedDomainEx *r)
1261 /* The result of a bad hair day from an IDL programmer? Not
1262 * implmented in Win2k3. You should always just lsa_Close
1264 return NT_STATUS_NOT_IMPLEMENTED;
1269 comparison function for sorting lsa_DomainInformation array
1271 static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
1273 return strcasecmp_m(e1->name.string, e2->name.string);
1279 static NTSTATUS lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1280 struct lsa_EnumTrustDom *r)
1282 struct dcesrv_handle *policy_handle;
1283 struct lsa_DomainInfo *entries;
1284 struct lsa_policy_state *policy_state;
1285 struct ldb_message **domains;
1286 const char *attrs[] = {
1288 "securityIdentifier",
1295 *r->out.resume_handle = 0;
1297 r->out.domains->domains = NULL;
1298 r->out.domains->count = 0;
1300 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1302 policy_state = policy_handle->data;
1304 /* search for all users in this domain. This could possibly be cached and
1305 resumed based on resume_key */
1306 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1307 "objectclass=trustedDomain");
1309 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1311 if (count == 0 || r->in.max_size == 0) {
1312 return NT_STATUS_OK;
1315 /* convert to lsa_TrustInformation format */
1316 entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
1318 return NT_STATUS_NO_MEMORY;
1320 for (i=0;i<count;i++) {
1321 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
1322 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
1325 /* sort the results by name */
1326 qsort(entries, count, sizeof(*entries),
1327 (comparison_fn_t)compare_DomainInfo);
1329 if (*r->in.resume_handle >= count) {
1330 *r->out.resume_handle = -1;
1332 return NT_STATUS_NO_MORE_ENTRIES;
1335 /* return the rest, limit by max_size. Note that we
1336 use the w2k3 element size value of 60 */
1337 r->out.domains->count = count - *r->in.resume_handle;
1338 r->out.domains->count = MIN(r->out.domains->count,
1339 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
1341 r->out.domains->domains = entries + *r->in.resume_handle;
1342 r->out.domains->count = r->out.domains->count;
1344 if (r->out.domains->count < count - *r->in.resume_handle) {
1345 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1346 return STATUS_MORE_ENTRIES;
1349 return NT_STATUS_OK;
1353 comparison function for sorting lsa_DomainInformation array
1355 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
1357 return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
1361 lsa_EnumTrustedDomainsEx
1363 static NTSTATUS lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1364 struct lsa_EnumTrustedDomainsEx *r)
1366 struct dcesrv_handle *policy_handle;
1367 struct lsa_TrustDomainInfoInfoEx *entries;
1368 struct lsa_policy_state *policy_state;
1369 struct ldb_message **domains;
1370 const char *attrs[] = {
1373 "securityIdentifier",
1383 *r->out.resume_handle = 0;
1385 r->out.domains->domains = NULL;
1386 r->out.domains->count = 0;
1388 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1390 policy_state = policy_handle->data;
1392 /* search for all users in this domain. This could possibly be cached and
1393 resumed based on resume_key */
1394 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1395 "objectclass=trustedDomain");
1397 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1399 if (count == 0 || r->in.max_size == 0) {
1400 return NT_STATUS_OK;
1403 /* convert to lsa_DomainInformation format */
1404 entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
1406 return NT_STATUS_NO_MEMORY;
1408 for (i=0;i<count;i++) {
1409 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
1410 if (!NT_STATUS_IS_OK(nt_status)) {
1415 /* sort the results by name */
1416 qsort(entries, count, sizeof(*entries),
1417 (comparison_fn_t)compare_TrustDomainInfoInfoEx);
1419 if (*r->in.resume_handle >= count) {
1420 *r->out.resume_handle = -1;
1422 return NT_STATUS_NO_MORE_ENTRIES;
1425 /* return the rest, limit by max_size. Note that we
1426 use the w2k3 element size value of 60 */
1427 r->out.domains->count = count - *r->in.resume_handle;
1428 r->out.domains->count = MIN(r->out.domains->count,
1429 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
1431 r->out.domains->domains = entries + *r->in.resume_handle;
1432 r->out.domains->count = r->out.domains->count;
1434 if (r->out.domains->count < count - *r->in.resume_handle) {
1435 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1436 return STATUS_MORE_ENTRIES;
1439 return NT_STATUS_OK;
1444 return the authority name and authority sid, given a sid
1446 static NTSTATUS lsa_authority_name(struct lsa_policy_state *state,
1447 TALLOC_CTX *mem_ctx, struct dom_sid *sid,
1448 const char **authority_name,
1449 struct dom_sid **authority_sid)
1451 if (dom_sid_in_domain(state->domain_sid, sid)) {
1452 *authority_name = state->domain_name;
1453 *authority_sid = state->domain_sid;
1454 return NT_STATUS_OK;
1457 if (dom_sid_in_domain(state->builtin_sid, sid)) {
1458 *authority_name = "BUILTIN";
1459 *authority_sid = state->builtin_sid;
1460 return NT_STATUS_OK;
1463 *authority_sid = dom_sid_dup(mem_ctx, sid);
1464 if (*authority_sid == NULL) {
1465 return NT_STATUS_NO_MEMORY;
1467 (*authority_sid)->num_auths = 0;
1468 *authority_name = dom_sid_string(mem_ctx, *authority_sid);
1469 if (*authority_name == NULL) {
1470 return NT_STATUS_NO_MEMORY;
1473 return NT_STATUS_OK;
1477 add to the lsa_RefDomainList for LookupSids and LookupNames
1479 static NTSTATUS lsa_authority_list(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
1480 struct dom_sid *sid,
1481 struct lsa_RefDomainList *domains,
1482 uint32_t *sid_index)
1485 const char *authority_name;
1486 struct dom_sid *authority_sid;
1489 /* work out the authority name */
1490 status = lsa_authority_name(state, mem_ctx, sid,
1491 &authority_name, &authority_sid);
1492 if (!NT_STATUS_IS_OK(status)) {
1496 /* see if we've already done this authority name */
1497 for (i=0;i<domains->count;i++) {
1498 if (strcmp(authority_name, domains->domains[i].name.string) == 0) {
1500 return NT_STATUS_OK;
1504 domains->domains = talloc_realloc(domains,
1506 struct lsa_DomainInfo,
1508 if (domains->domains == NULL) {
1509 return NT_STATUS_NO_MEMORY;
1511 domains->domains[i].name.string = authority_name;
1512 domains->domains[i].sid = authority_sid;
1514 domains->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER * domains->count;
1517 return NT_STATUS_OK;
1521 lookup a name for 1 SID
1523 static NTSTATUS lsa_lookup_sid(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
1524 struct dom_sid *sid, const char *sid_str,
1525 const char **name, uint32_t *atype)
1528 struct ldb_message **res;
1529 const char * const attrs[] = { "sAMAccountName", "sAMAccountType", "name", NULL};
1532 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
1533 "objectSid=%s", ldap_encode_ndr_dom_sid(mem_ctx, sid));
1535 *name = ldb_msg_find_attr_as_string(res[0], "sAMAccountName", NULL);
1537 *name = ldb_msg_find_attr_as_string(res[0], "name", NULL);
1539 *name = talloc_strdup(mem_ctx, sid_str);
1540 NT_STATUS_HAVE_NO_MEMORY(*name);
1544 *atype = samdb_result_uint(res[0], "sAMAccountType", 0);
1546 return NT_STATUS_OK;
1549 status = sidmap_allocated_sid_lookup(state->sidmap, mem_ctx, sid, name, atype);
1558 static NTSTATUS lsa_LookupSids2(struct dcesrv_call_state *dce_call,
1559 TALLOC_CTX *mem_ctx,
1560 struct lsa_LookupSids2 *r)
1562 struct lsa_policy_state *state;
1564 NTSTATUS status = NT_STATUS_OK;
1566 r->out.domains = NULL;
1568 status = lsa_get_policy_state(dce_call, mem_ctx, &state);
1569 if (!NT_STATUS_IS_OK(status)) {
1573 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
1574 if (r->out.domains == NULL) {
1575 return NT_STATUS_NO_MEMORY;
1578 r->out.names = talloc_zero(mem_ctx, struct lsa_TransNameArray2);
1579 if (r->out.names == NULL) {
1580 return NT_STATUS_NO_MEMORY;
1585 r->out.names->names = talloc_array(r->out.names, struct lsa_TranslatedName2,
1586 r->in.sids->num_sids);
1587 if (r->out.names->names == NULL) {
1588 return NT_STATUS_NO_MEMORY;
1591 for (i=0;i<r->in.sids->num_sids;i++) {
1592 struct dom_sid *sid = r->in.sids->sids[i].sid;
1593 char *sid_str = dom_sid_string(mem_ctx, sid);
1595 uint32_t atype, rtype, sid_index;
1598 r->out.names->count++;
1601 r->out.names->names[i].sid_type = SID_NAME_UNKNOWN;
1602 r->out.names->names[i].name.string = sid_str;
1603 r->out.names->names[i].sid_index = 0xFFFFFFFF;
1604 r->out.names->names[i].unknown = 0;
1606 if (sid_str == NULL) {
1607 r->out.names->names[i].name.string = "(SIDERROR)";
1608 status = STATUS_SOME_UNMAPPED;
1612 /* work out the authority name */
1613 status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
1614 if (!NT_STATUS_IS_OK(status2)) {
1618 status2 = lsa_lookup_sid(state, mem_ctx, sid, sid_str,
1620 if (!NT_STATUS_IS_OK(status2)) {
1621 status = STATUS_SOME_UNMAPPED;
1625 rtype = samdb_atype_map(atype);
1626 if (rtype == SID_NAME_UNKNOWN) {
1627 status = STATUS_SOME_UNMAPPED;
1631 r->out.names->names[i].sid_type = rtype;
1632 r->out.names->names[i].name.string = name;
1633 r->out.names->names[i].sid_index = sid_index;
1634 r->out.names->names[i].unknown = 0;
1644 Identical to LookupSids2, but doesn't take a policy handle
1647 static NTSTATUS lsa_LookupSids3(struct dcesrv_call_state *dce_call,
1648 TALLOC_CTX *mem_ctx,
1649 struct lsa_LookupSids3 *r)
1651 struct lsa_LookupSids2 r2;
1652 struct lsa_OpenPolicy2 pol;
1654 struct dcesrv_handle *h;
1656 /* No policy handle on the wire, so make one up here */
1657 r2.in.handle = talloc(mem_ctx, struct policy_handle);
1658 if (!r2.in.handle) {
1659 return NT_STATUS_NO_MEMORY;
1662 pol.out.handle = r2.in.handle;
1663 pol.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1665 pol.in.system_name = NULL;
1666 status = lsa_OpenPolicy2(dce_call, mem_ctx, &pol);
1667 if (!NT_STATUS_IS_OK(status)) {
1671 /* ensure this handle goes away at the end of this call */
1672 DCESRV_PULL_HANDLE(h, r2.in.handle, LSA_HANDLE_POLICY);
1673 talloc_steal(mem_ctx, h);
1675 r2.in.sids = r->in.sids;
1676 r2.in.names = r->in.names;
1677 r2.in.level = r->in.level;
1678 r2.in.count = r->in.count;
1679 r2.in.unknown1 = r->in.unknown1;
1680 r2.in.unknown2 = r->in.unknown2;
1681 r2.out.count = r->out.count;
1682 r2.out.names = r->out.names;
1684 status = lsa_LookupSids2(dce_call, mem_ctx, &r2);
1685 if (dce_call->fault_code != 0) {
1689 r->out.domains = r2.out.domains;
1690 r->out.names = r2.out.names;
1691 r->out.count = r2.out.count;
1700 static NTSTATUS lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1701 struct lsa_LookupSids *r)
1703 struct lsa_LookupSids2 r2;
1707 r2.in.handle = r->in.handle;
1708 r2.in.sids = r->in.sids;
1710 r2.in.level = r->in.level;
1711 r2.in.count = r->in.count;
1714 r2.out.count = r->out.count;
1715 r2.out.names = NULL;
1717 status = lsa_LookupSids2(dce_call, mem_ctx, &r2);
1718 if (dce_call->fault_code != 0) {
1722 r->out.domains = r2.out.domains;
1723 if (!r2.out.names) {
1724 r->out.names = NULL;
1728 r->out.names = talloc(mem_ctx, struct lsa_TransNameArray);
1729 if (r->out.names == NULL) {
1730 return NT_STATUS_NO_MEMORY;
1732 r->out.names->count = r2.out.names->count;
1733 r->out.names->names = talloc_array(r->out.names, struct lsa_TranslatedName,
1734 r->out.names->count);
1735 if (r->out.names->names == NULL) {
1736 return NT_STATUS_NO_MEMORY;
1738 for (i=0;i<r->out.names->count;i++) {
1739 r->out.names->names[i].sid_type = r2.out.names->names[i].sid_type;
1740 r->out.names->names[i].name.string = r2.out.names->names[i].name.string;
1741 r->out.names->names[i].sid_index = r2.out.names->names[i].sid_index;
1751 static NTSTATUS lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1752 struct lsa_OpenAccount *r)
1754 struct dcesrv_handle *h, *ah;
1755 struct lsa_policy_state *state;
1756 struct lsa_account_state *astate;
1758 ZERO_STRUCTP(r->out.acct_handle);
1760 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1764 astate = talloc(dce_call->conn, struct lsa_account_state);
1765 if (astate == NULL) {
1766 return NT_STATUS_NO_MEMORY;
1769 astate->account_sid = dom_sid_dup(astate, r->in.sid);
1770 if (astate->account_sid == NULL) {
1771 talloc_free(astate);
1772 return NT_STATUS_NO_MEMORY;
1775 astate->policy = talloc_reference(astate, state);
1776 astate->access_mask = r->in.access_mask;
1778 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
1780 talloc_free(astate);
1781 return NT_STATUS_NO_MEMORY;
1784 ah->data = talloc_steal(ah, astate);
1786 *r->out.acct_handle = ah->wire_handle;
1788 return NT_STATUS_OK;
1793 lsa_EnumPrivsAccount
1795 static NTSTATUS lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
1796 TALLOC_CTX *mem_ctx,
1797 struct lsa_EnumPrivsAccount *r)
1799 struct dcesrv_handle *h;
1800 struct lsa_account_state *astate;
1802 struct ldb_message **res;
1803 const char * const attrs[] = { "privilege", NULL};
1804 struct ldb_message_element *el;
1807 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1811 r->out.privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
1812 r->out.privs->count = 0;
1813 r->out.privs->unknown = 0;
1814 r->out.privs->set = NULL;
1816 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
1817 if (sidstr == NULL) {
1818 return NT_STATUS_NO_MEMORY;
1821 ret = gendb_search(astate->policy->sam_ldb, mem_ctx, NULL, &res, attrs,
1822 "objectSid=%s", sidstr);
1824 return NT_STATUS_OK;
1827 el = ldb_msg_find_element(res[0], "privilege");
1828 if (el == NULL || el->num_values == 0) {
1829 return NT_STATUS_OK;
1832 r->out.privs->set = talloc_array(r->out.privs,
1833 struct lsa_LUIDAttribute, el->num_values);
1834 if (r->out.privs->set == NULL) {
1835 return NT_STATUS_NO_MEMORY;
1838 for (i=0;i<el->num_values;i++) {
1839 int id = sec_privilege_id((const char *)el->values[i].data);
1841 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1843 r->out.privs->set[i].attribute = 0;
1844 r->out.privs->set[i].luid.low = id;
1845 r->out.privs->set[i].luid.high = 0;
1848 r->out.privs->count = el->num_values;
1850 return NT_STATUS_OK;
1854 lsa_EnumAccountRights
1856 static NTSTATUS lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
1857 TALLOC_CTX *mem_ctx,
1858 struct lsa_EnumAccountRights *r)
1860 struct dcesrv_handle *h;
1861 struct lsa_policy_state *state;
1863 struct ldb_message **res;
1864 const char * const attrs[] = { "privilege", NULL};
1866 struct ldb_message_element *el;
1868 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1872 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
1873 if (sidstr == NULL) {
1874 return NT_STATUS_NO_MEMORY;
1877 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
1878 "(&(objectSid=%s)(privilege=*))", sidstr);
1880 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1883 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1886 DEBUG(3, ("searching for account rights for SID: %s failed: %s",
1887 dom_sid_string(mem_ctx, r->in.sid),
1888 ldb_errstring(state->sam_ldb)));
1889 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1892 el = ldb_msg_find_element(res[0], "privilege");
1893 if (el == NULL || el->num_values == 0) {
1894 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1897 r->out.rights->count = el->num_values;
1898 r->out.rights->names = talloc_array(r->out.rights,
1899 struct lsa_StringLarge, r->out.rights->count);
1900 if (r->out.rights->names == NULL) {
1901 return NT_STATUS_NO_MEMORY;
1904 for (i=0;i<el->num_values;i++) {
1905 r->out.rights->names[i].string = (const char *)el->values[i].data;
1908 return NT_STATUS_OK;
1914 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
1916 static NTSTATUS lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
1917 TALLOC_CTX *mem_ctx,
1918 struct lsa_policy_state *state,
1920 struct dom_sid *sid,
1921 const struct lsa_RightSet *rights)
1924 struct ldb_message *msg;
1925 struct ldb_message_element *el;
1927 struct lsa_EnumAccountRights r2;
1929 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, sid);
1930 if (sidstr == NULL) {
1931 return NT_STATUS_NO_MEMORY;
1934 msg = ldb_msg_new(mem_ctx);
1936 return NT_STATUS_NO_MEMORY;
1939 msg->dn = samdb_search_dn(state->sam_ldb, mem_ctx,
1940 NULL, "objectSid=%s", sidstr);
1941 if (msg->dn == NULL) {
1943 if (ldb_flag == LDB_FLAG_MOD_DELETE) {
1944 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1946 status = samdb_create_foreign_security_principal(state->sam_ldb, mem_ctx,
1948 if (!NT_STATUS_IS_OK(status)) {
1951 return NT_STATUS_NO_SUCH_USER;
1954 if (ldb_msg_add_empty(msg, "privilege", ldb_flag, NULL)) {
1955 return NT_STATUS_NO_MEMORY;
1958 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1961 r2.in.handle = &state->handle->wire_handle;
1963 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
1965 status = lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1966 if (!NT_STATUS_IS_OK(status)) {
1967 ZERO_STRUCTP(r2.out.rights);
1971 for (i=0;i<rights->count;i++) {
1972 if (sec_privilege_id(rights->names[i].string) == -1) {
1973 return NT_STATUS_NO_SUCH_PRIVILEGE;
1976 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1978 for (j=0;j<r2.out.rights->count;j++) {
1979 if (strcasecmp_m(r2.out.rights->names[j].string,
1980 rights->names[i].string) == 0) {
1984 if (j != r2.out.rights->count) continue;
1987 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
1988 if (ret != LDB_SUCCESS) {
1989 return NT_STATUS_NO_MEMORY;
1993 el = ldb_msg_find_element(msg, "privilege");
1995 return NT_STATUS_OK;
1998 ret = samdb_modify(state->sam_ldb, mem_ctx, msg);
2000 if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
2001 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2003 DEBUG(3, ("Could not %s attributes from %s: %s",
2004 ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add",
2005 ldb_dn_get_linearized(msg->dn), ldb_errstring(state->sam_ldb)));
2006 return NT_STATUS_UNEXPECTED_IO_ERROR;
2009 return NT_STATUS_OK;
2013 lsa_AddPrivilegesToAccount
2015 static NTSTATUS lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2016 struct lsa_AddPrivilegesToAccount *r)
2018 struct lsa_RightSet rights;
2019 struct dcesrv_handle *h;
2020 struct lsa_account_state *astate;
2023 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2027 rights.count = r->in.privs->count;
2028 rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
2029 if (rights.names == NULL) {
2030 return NT_STATUS_NO_MEMORY;
2032 for (i=0;i<rights.count;i++) {
2033 int id = r->in.privs->set[i].luid.low;
2034 if (r->in.privs->set[i].luid.high) {
2035 return NT_STATUS_NO_SUCH_PRIVILEGE;
2037 rights.names[i].string = sec_privilege_name(id);
2038 if (rights.names[i].string == NULL) {
2039 return NT_STATUS_NO_SUCH_PRIVILEGE;
2043 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2044 LDB_FLAG_MOD_ADD, astate->account_sid,
2050 lsa_RemovePrivilegesFromAccount
2052 static NTSTATUS lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2053 struct lsa_RemovePrivilegesFromAccount *r)
2055 struct lsa_RightSet *rights;
2056 struct dcesrv_handle *h;
2057 struct lsa_account_state *astate;
2060 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2064 rights = talloc(mem_ctx, struct lsa_RightSet);
2066 if (r->in.remove_all == 1 &&
2067 r->in.privs == NULL) {
2068 struct lsa_EnumAccountRights r2;
2071 r2.in.handle = &astate->policy->handle->wire_handle;
2072 r2.in.sid = astate->account_sid;
2073 r2.out.rights = rights;
2075 status = lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
2076 if (!NT_STATUS_IS_OK(status)) {
2080 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2081 LDB_FLAG_MOD_DELETE, astate->account_sid,
2085 if (r->in.remove_all != 0) {
2086 return NT_STATUS_INVALID_PARAMETER;
2089 rights->count = r->in.privs->count;
2090 rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
2091 if (rights->names == NULL) {
2092 return NT_STATUS_NO_MEMORY;
2094 for (i=0;i<rights->count;i++) {
2095 int id = r->in.privs->set[i].luid.low;
2096 if (r->in.privs->set[i].luid.high) {
2097 return NT_STATUS_NO_SUCH_PRIVILEGE;
2099 rights->names[i].string = sec_privilege_name(id);
2100 if (rights->names[i].string == NULL) {
2101 return NT_STATUS_NO_SUCH_PRIVILEGE;
2105 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2106 LDB_FLAG_MOD_DELETE, astate->account_sid,
2112 lsa_GetQuotasForAccount
2114 static NTSTATUS lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2115 struct lsa_GetQuotasForAccount *r)
2117 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2122 lsa_SetQuotasForAccount
2124 static NTSTATUS lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2125 struct lsa_SetQuotasForAccount *r)
2127 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2132 lsa_GetSystemAccessAccount
2134 static NTSTATUS lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2135 struct lsa_GetSystemAccessAccount *r)
2137 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2142 lsa_SetSystemAccessAccount
2144 static NTSTATUS lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2145 struct lsa_SetSystemAccessAccount *r)
2147 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2154 static NTSTATUS lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2155 struct lsa_CreateSecret *r)
2157 struct dcesrv_handle *policy_handle;
2158 struct lsa_policy_state *policy_state;
2159 struct lsa_secret_state *secret_state;
2160 struct dcesrv_handle *handle;
2161 struct ldb_message **msgs, *msg;
2163 const char *attrs[] = {
2171 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2172 ZERO_STRUCTP(r->out.sec_handle);
2174 policy_state = policy_handle->data;
2176 if (!r->in.name.string) {
2177 return NT_STATUS_INVALID_PARAMETER;
2180 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2181 if (!secret_state) {
2182 return NT_STATUS_NO_MEMORY;
2184 secret_state->policy = policy_state;
2186 msg = ldb_msg_new(mem_ctx);
2188 return NT_STATUS_NO_MEMORY;
2191 if (strncmp("G$", r->in.name.string, 2) == 0) {
2193 name = &r->in.name.string[2];
2194 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
2195 secret_state->global = True;
2197 if (strlen(name) < 1) {
2198 return NT_STATUS_INVALID_PARAMETER;
2201 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
2202 /* search for the secret record */
2203 ret = gendb_search(secret_state->sam_ldb,
2204 mem_ctx, policy_state->system_dn, &msgs, attrs,
2205 "(&(cn=%s)(objectclass=secret))",
2208 return NT_STATUS_OBJECT_NAME_COLLISION;
2212 DEBUG(0,("Failure searching for CN=%s: %s\n",
2213 name2, ldb_errstring(secret_state->sam_ldb)));
2214 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2217 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
2218 if (!name2 || ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
2219 return NT_STATUS_NO_MEMORY;
2222 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
2225 secret_state->global = False;
2227 name = r->in.name.string;
2228 if (strlen(name) < 1) {
2229 return NT_STATUS_INVALID_PARAMETER;
2232 secret_state->sam_ldb = talloc_reference(secret_state, secrets_db_connect(mem_ctx));
2233 /* search for the secret record */
2234 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2235 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2237 "(&(cn=%s)(objectclass=secret))",
2238 ldb_binary_encode_string(mem_ctx, name));
2240 return NT_STATUS_OBJECT_NAME_COLLISION;
2244 DEBUG(0,("Failure searching for CN=%s: %s\n",
2245 name, ldb_errstring(secret_state->sam_ldb)));
2246 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2249 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name);
2250 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
2253 /* pull in all the template attributes. Note this is always from the global samdb */
2254 ret = samdb_copy_template(secret_state->policy->sam_ldb, msg,
2255 "(&(cn=TemplateSecret)(objectclass=secretTemplate))", &errstr);
2257 DEBUG(0,("Failed to load TemplateSecret from samdb: %s\n",
2259 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2262 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
2264 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
2266 /* create the secret */
2267 ret = samdb_add(secret_state->sam_ldb, mem_ctx, msg);
2269 DEBUG(0,("Failed to create secret record %s: %s\n",
2270 ldb_dn_get_linearized(msg->dn),
2271 ldb_errstring(secret_state->sam_ldb)));
2272 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2275 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2277 return NT_STATUS_NO_MEMORY;
2280 handle->data = talloc_steal(handle, secret_state);
2282 secret_state->access_mask = r->in.access_mask;
2283 secret_state->policy = talloc_reference(secret_state, policy_state);
2285 *r->out.sec_handle = handle->wire_handle;
2287 return NT_STATUS_OK;
2294 static NTSTATUS lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2295 struct lsa_OpenSecret *r)
2297 struct dcesrv_handle *policy_handle;
2299 struct lsa_policy_state *policy_state;
2300 struct lsa_secret_state *secret_state;
2301 struct dcesrv_handle *handle;
2302 struct ldb_message **msgs;
2303 const char *attrs[] = {
2311 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2312 ZERO_STRUCTP(r->out.sec_handle);
2313 policy_state = policy_handle->data;
2315 if (!r->in.name.string) {
2316 return NT_STATUS_INVALID_PARAMETER;
2319 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2320 if (!secret_state) {
2321 return NT_STATUS_NO_MEMORY;
2323 secret_state->policy = policy_state;
2325 if (strncmp("G$", r->in.name.string, 2) == 0) {
2326 name = &r->in.name.string[2];
2327 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
2328 secret_state->global = True;
2330 if (strlen(name) < 1) {
2331 return NT_STATUS_INVALID_PARAMETER;
2334 /* search for the secret record */
2335 ret = gendb_search(secret_state->sam_ldb,
2336 mem_ctx, policy_state->system_dn, &msgs, attrs,
2337 "(&(cn=%s Secret)(objectclass=secret))",
2338 ldb_binary_encode_string(mem_ctx, name));
2340 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2344 DEBUG(0,("Found %d records matching DN %s\n", ret,
2345 ldb_dn_get_linearized(policy_state->system_dn)));
2346 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2350 secret_state->sam_ldb = talloc_reference(secret_state, secrets_db_connect(mem_ctx));
2352 secret_state->global = False;
2353 name = r->in.name.string;
2354 if (strlen(name) < 1) {
2355 return NT_STATUS_INVALID_PARAMETER;
2358 /* search for the secret record */
2359 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2360 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2362 "(&(cn=%s)(objectclass=secret))",
2363 ldb_binary_encode_string(mem_ctx, name));
2365 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2369 DEBUG(0,("Found %d records matching DN %s\n", ret,
2370 ldb_dn_get_linearized(policy_state->system_dn)));
2371 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2375 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
2377 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2379 return NT_STATUS_NO_MEMORY;
2382 handle->data = talloc_steal(handle, secret_state);
2384 secret_state->access_mask = r->in.access_mask;
2385 secret_state->policy = talloc_reference(secret_state, policy_state);
2387 *r->out.sec_handle = handle->wire_handle;
2389 return NT_STATUS_OK;
2396 static NTSTATUS lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2397 struct lsa_SetSecret *r)
2400 struct dcesrv_handle *h;
2401 struct lsa_secret_state *secret_state;
2402 struct ldb_message *msg;
2403 DATA_BLOB session_key;
2404 DATA_BLOB crypt_secret, secret;
2407 NTSTATUS status = NT_STATUS_OK;
2409 struct timeval now = timeval_current();
2410 NTTIME nt_now = timeval_to_nttime(&now);
2412 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2414 secret_state = h->data;
2416 msg = ldb_msg_new(mem_ctx);
2418 return NT_STATUS_NO_MEMORY;
2421 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
2423 return NT_STATUS_NO_MEMORY;
2425 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2426 if (!NT_STATUS_IS_OK(status)) {
2430 if (r->in.old_val) {
2432 crypt_secret.data = r->in.old_val->data;
2433 crypt_secret.length = r->in.old_val->size;
2435 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2436 if (!NT_STATUS_IS_OK(status)) {
2440 val.data = secret.data;
2441 val.length = secret.length;
2444 if (samdb_msg_add_value(secret_state->sam_ldb,
2445 mem_ctx, msg, "priorValue", &val) != 0) {
2446 return NT_STATUS_NO_MEMORY;
2449 /* set old value mtime */
2450 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2451 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
2452 return NT_STATUS_NO_MEMORY;
2455 if (!r->in.new_val) {
2456 /* This behaviour varies depending of if this is a local, or a global secret... */
2457 if (secret_state->global) {
2458 /* set old value mtime */
2459 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2460 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2461 return NT_STATUS_NO_MEMORY;
2464 if (samdb_msg_add_delete(secret_state->sam_ldb,
2465 mem_ctx, msg, "currentValue")) {
2466 return NT_STATUS_NO_MEMORY;
2468 if (samdb_msg_add_delete(secret_state->sam_ldb,
2469 mem_ctx, msg, "lastSetTime")) {
2470 return NT_STATUS_NO_MEMORY;
2476 if (r->in.new_val) {
2478 crypt_secret.data = r->in.new_val->data;
2479 crypt_secret.length = r->in.new_val->size;
2481 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2482 if (!NT_STATUS_IS_OK(status)) {
2486 val.data = secret.data;
2487 val.length = secret.length;
2490 if (samdb_msg_add_value(secret_state->sam_ldb,
2491 mem_ctx, msg, "currentValue", &val) != 0) {
2492 return NT_STATUS_NO_MEMORY;
2495 /* set new value mtime */
2496 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2497 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2498 return NT_STATUS_NO_MEMORY;
2501 /* If the old value is not set, then migrate the
2502 * current value to the old value */
2503 if (!r->in.old_val) {
2504 const struct ldb_val *new_val;
2505 NTTIME last_set_time;
2506 struct ldb_message **res;
2507 const char *attrs[] = {
2513 /* search for the secret record */
2514 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
2515 secret_state->secret_dn, &res, attrs);
2517 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2521 DEBUG(0,("Found %d records matching dn=%s\n", ret,
2522 ldb_dn_get_linearized(secret_state->secret_dn)));
2523 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2526 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2527 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2531 if (samdb_msg_add_value(secret_state->sam_ldb,
2532 mem_ctx, msg, "priorValue",
2534 return NT_STATUS_NO_MEMORY;
2538 /* set new value mtime */
2539 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2540 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2541 mem_ctx, msg, "priorSetTime", last_set_time) != 0) {
2542 return NT_STATUS_NO_MEMORY;
2548 /* modify the samdb record */
2549 ret = samdb_replace(secret_state->sam_ldb, mem_ctx, msg);
2551 /* we really need samdb.c to return NTSTATUS */
2552 return NT_STATUS_UNSUCCESSFUL;
2555 return NT_STATUS_OK;
2562 static NTSTATUS lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2563 struct lsa_QuerySecret *r)
2565 struct dcesrv_handle *h;
2566 struct lsa_secret_state *secret_state;
2567 struct ldb_message *msg;
2568 DATA_BLOB session_key;
2569 DATA_BLOB crypt_secret, secret;
2571 struct ldb_message **res;
2572 const char *attrs[] = {
2582 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2584 secret_state = h->data;
2586 /* pull all the user attributes */
2587 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2588 secret_state->secret_dn, &res, attrs);
2590 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2594 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2595 if (!NT_STATUS_IS_OK(nt_status)) {
2599 if (r->in.old_val) {
2600 const struct ldb_val *prior_val;
2601 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2602 if (!r->out.old_val) {
2603 return NT_STATUS_NO_MEMORY;
2605 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
2607 if (prior_val && prior_val->length) {
2608 secret.data = prior_val->data;
2609 secret.length = prior_val->length;
2612 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2613 if (!crypt_secret.length) {
2614 return NT_STATUS_NO_MEMORY;
2616 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2617 if (!r->out.old_val->buf) {
2618 return NT_STATUS_NO_MEMORY;
2620 r->out.old_val->buf->size = crypt_secret.length;
2621 r->out.old_val->buf->length = crypt_secret.length;
2622 r->out.old_val->buf->data = crypt_secret.data;
2626 if (r->in.old_mtime) {
2627 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2628 if (!r->out.old_mtime) {
2629 return NT_STATUS_NO_MEMORY;
2631 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
2634 if (r->in.new_val) {
2635 const struct ldb_val *new_val;
2636 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2637 if (!r->out.new_val) {
2638 return NT_STATUS_NO_MEMORY;
2641 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2643 if (new_val && new_val->length) {
2644 secret.data = new_val->data;
2645 secret.length = new_val->length;
2648 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2649 if (!crypt_secret.length) {
2650 return NT_STATUS_NO_MEMORY;
2652 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2653 if (!r->out.new_val->buf) {
2654 return NT_STATUS_NO_MEMORY;
2656 r->out.new_val->buf->length = crypt_secret.length;
2657 r->out.new_val->buf->size = crypt_secret.length;
2658 r->out.new_val->buf->data = crypt_secret.data;
2662 if (r->in.new_mtime) {
2663 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2664 if (!r->out.new_mtime) {
2665 return NT_STATUS_NO_MEMORY;
2667 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2670 return NT_STATUS_OK;
2677 static NTSTATUS lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
2678 TALLOC_CTX *mem_ctx,
2679 struct lsa_LookupPrivValue *r)
2681 struct dcesrv_handle *h;
2682 struct lsa_policy_state *state;
2685 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2689 id = sec_privilege_id(r->in.name->string);
2691 return NT_STATUS_NO_SUCH_PRIVILEGE;
2694 r->out.luid->low = id;
2695 r->out.luid->high = 0;
2697 return NT_STATUS_OK;
2704 static NTSTATUS lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
2705 TALLOC_CTX *mem_ctx,
2706 struct lsa_LookupPrivName *r)
2708 struct dcesrv_handle *h;
2709 struct lsa_policy_state *state;
2710 const char *privname;
2712 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2716 if (r->in.luid->high != 0) {
2717 return NT_STATUS_NO_SUCH_PRIVILEGE;
2720 privname = sec_privilege_name(r->in.luid->low);
2721 if (privname == NULL) {
2722 return NT_STATUS_NO_SUCH_PRIVILEGE;
2725 r->out.name = talloc(mem_ctx, struct lsa_StringLarge);
2726 if (r->out.name == NULL) {
2727 return NT_STATUS_NO_MEMORY;
2729 r->out.name->string = privname;
2731 return NT_STATUS_OK;
2736 lsa_LookupPrivDisplayName
2738 static NTSTATUS lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
2739 TALLOC_CTX *mem_ctx,
2740 struct lsa_LookupPrivDisplayName *r)
2742 struct dcesrv_handle *h;
2743 struct lsa_policy_state *state;
2746 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2750 id = sec_privilege_id(r->in.name->string);
2752 return NT_STATUS_NO_SUCH_PRIVILEGE;
2755 r->out.disp_name = talloc(mem_ctx, struct lsa_StringLarge);
2756 if (r->out.disp_name == NULL) {
2757 return NT_STATUS_NO_MEMORY;
2760 r->out.disp_name->string = sec_privilege_display_name(id, r->in.language_id);
2761 if (r->out.disp_name->string == NULL) {
2762 return NT_STATUS_INTERNAL_ERROR;
2765 return NT_STATUS_OK;
2772 static NTSTATUS lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2773 struct lsa_DeleteObject *r)
2775 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2780 lsa_EnumAccountsWithUserRight
2782 static NTSTATUS lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
2783 TALLOC_CTX *mem_ctx,
2784 struct lsa_EnumAccountsWithUserRight *r)
2786 struct dcesrv_handle *h;
2787 struct lsa_policy_state *state;
2789 struct ldb_message **res;
2790 const char * const attrs[] = { "objectSid", NULL};
2791 const char *privname;
2793 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2797 if (r->in.name == NULL) {
2798 return NT_STATUS_NO_SUCH_PRIVILEGE;
2801 privname = r->in.name->string;
2802 if (sec_privilege_id(privname) == -1) {
2803 return NT_STATUS_NO_SUCH_PRIVILEGE;
2806 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
2807 "privilege=%s", privname);
2809 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2812 return NT_STATUS_NO_MORE_ENTRIES;
2815 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2816 if (r->out.sids->sids == NULL) {
2817 return NT_STATUS_NO_MEMORY;
2819 for (i=0;i<ret;i++) {
2820 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2821 res[i], "objectSid");
2822 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2824 r->out.sids->num_sids = ret;
2826 return NT_STATUS_OK;
2831 lsa_AddAccountRights
2833 static NTSTATUS lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
2834 TALLOC_CTX *mem_ctx,
2835 struct lsa_AddAccountRights *r)
2837 struct dcesrv_handle *h;
2838 struct lsa_policy_state *state;
2840 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2844 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2846 r->in.sid, r->in.rights);
2851 lsa_RemoveAccountRights
2853 static NTSTATUS lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
2854 TALLOC_CTX *mem_ctx,
2855 struct lsa_RemoveAccountRights *r)
2857 struct dcesrv_handle *h;
2858 struct lsa_policy_state *state;
2860 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2864 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2865 LDB_FLAG_MOD_DELETE,
2866 r->in.sid, r->in.rights);
2871 lsa_StorePrivateData
2873 static NTSTATUS lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2874 struct lsa_StorePrivateData *r)
2876 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2881 lsa_RetrievePrivateData
2883 static NTSTATUS lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2884 struct lsa_RetrievePrivateData *r)
2886 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2893 static NTSTATUS lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2894 struct lsa_GetUserName *r)
2896 NTSTATUS status = NT_STATUS_OK;
2897 const char *account_name;
2898 const char *authority_name;
2899 struct lsa_String *_account_name;
2900 struct lsa_StringPointer *_authority_name = NULL;
2902 /* this is what w2k3 does */
2903 r->out.account_name = r->in.account_name;
2904 r->out.authority_name = r->in.authority_name;
2906 if (r->in.account_name && r->in.account_name->string) {
2907 return NT_STATUS_INVALID_PARAMETER;
2910 if (r->in.authority_name &&
2911 r->in.authority_name->string &&
2912 r->in.authority_name->string->string) {
2913 return NT_STATUS_INVALID_PARAMETER;
2916 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
2917 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
2919 _account_name = talloc(mem_ctx, struct lsa_String);
2920 NT_STATUS_HAVE_NO_MEMORY(_account_name);
2921 _account_name->string = account_name;
2923 if (r->in.authority_name) {
2924 _authority_name = talloc(mem_ctx, struct lsa_StringPointer);
2925 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
2926 _authority_name->string = talloc(mem_ctx, struct lsa_String);
2927 NT_STATUS_HAVE_NO_MEMORY(_authority_name->string);
2928 _authority_name->string->string = authority_name;
2931 r->out.account_name = _account_name;
2932 r->out.authority_name = _authority_name;
2940 static NTSTATUS lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
2941 TALLOC_CTX *mem_ctx,
2942 struct lsa_SetInfoPolicy2 *r)
2944 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2948 lsa_QueryDomainInformationPolicy
2950 static NTSTATUS lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2951 TALLOC_CTX *mem_ctx,
2952 struct lsa_QueryDomainInformationPolicy *r)
2954 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2958 lsa_SetDomInfoPolicy
2960 static NTSTATUS lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2961 TALLOC_CTX *mem_ctx,
2962 struct lsa_SetDomainInformationPolicy *r)
2964 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2970 static NTSTATUS lsa_TestCall(struct dcesrv_call_state *dce_call,
2971 TALLOC_CTX *mem_ctx,
2972 struct lsa_TestCall *r)
2974 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2978 lookup a SID for 1 name
2980 static NTSTATUS lsa_lookup_name(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
2981 const char *name, struct dom_sid **sid, uint32_t *atype)
2984 struct ldb_message **res;
2985 const char * const attrs[] = { "objectSid", "sAMAccountType", NULL};
2988 p = strchr_m(name, '\\');
2990 /* TODO: properly parse the domain prefix here, and use it to
2995 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs, "sAMAccountName=%s", ldb_binary_encode_string(mem_ctx, name));
2997 *sid = samdb_result_dom_sid(mem_ctx, res[0], "objectSid");
2999 return NT_STATUS_INVALID_SID;
3002 *atype = samdb_result_uint(res[0], "sAMAccountType", 0);
3004 return NT_STATUS_OK;
3007 /* need to add a call into sidmap to check for a allocated sid */
3009 return NT_STATUS_INVALID_SID;
3016 static NTSTATUS lsa_LookupNames3(struct dcesrv_call_state *dce_call,
3017 TALLOC_CTX *mem_ctx,
3018 struct lsa_LookupNames3 *r)
3020 struct lsa_policy_state *policy_state;
3021 struct dcesrv_handle *policy_handle;
3023 NTSTATUS status = NT_STATUS_OK;
3025 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
3027 policy_state = policy_handle->data;
3029 r->out.domains = NULL;
3031 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
3032 if (r->out.domains == NULL) {
3033 return NT_STATUS_NO_MEMORY;
3036 r->out.sids = talloc_zero(mem_ctx, struct lsa_TransSidArray3);
3037 if (r->out.sids == NULL) {
3038 return NT_STATUS_NO_MEMORY;
3043 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid3,
3045 if (r->out.sids->sids == NULL) {
3046 return NT_STATUS_NO_MEMORY;
3049 for (i=0;i<r->in.num_names;i++) {
3050 const char *name = r->in.names[i].string;
3051 struct dom_sid *sid;
3052 uint32_t atype, rtype, sid_index;
3055 r->out.sids->count++;
3058 r->out.sids->sids[i].sid_type = SID_NAME_UNKNOWN;
3059 r->out.sids->sids[i].sid = NULL;
3060 r->out.sids->sids[i].sid_index = 0xFFFFFFFF;
3061 r->out.sids->sids[i].unknown = 0;
3063 status2 = lsa_lookup_name(policy_state, mem_ctx, name, &sid, &atype);
3064 if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
3065 status = STATUS_SOME_UNMAPPED;
3069 rtype = samdb_atype_map(atype);
3070 if (rtype == SID_NAME_UNKNOWN) {
3071 status = STATUS_SOME_UNMAPPED;
3075 status2 = lsa_authority_list(policy_state, mem_ctx, sid, r->out.domains, &sid_index);
3076 if (!NT_STATUS_IS_OK(status2)) {
3080 r->out.sids->sids[i].sid_type = rtype;
3081 r->out.sids->sids[i].sid = sid;
3082 r->out.sids->sids[i].sid_index = sid_index;
3083 r->out.sids->sids[i].unknown = 0;
3092 Identical to LookupNames3, but doesn't take a policy handle
3095 static NTSTATUS lsa_LookupNames4(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3096 struct lsa_LookupNames4 *r)
3098 struct lsa_LookupNames3 r2;
3099 struct lsa_OpenPolicy2 pol;
3101 struct dcesrv_handle *h;
3103 /* No policy handle on the wire, so make one up here */
3104 r2.in.handle = talloc(mem_ctx, struct policy_handle);
3105 if (!r2.in.handle) {
3106 return NT_STATUS_NO_MEMORY;
3109 pol.out.handle = r2.in.handle;
3110 pol.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3112 pol.in.system_name = NULL;
3113 status = lsa_OpenPolicy2(dce_call, mem_ctx, &pol);
3114 if (!NT_STATUS_IS_OK(status)) {
3118 /* ensure this handle goes away at the end of this call */
3119 DCESRV_PULL_HANDLE(h, r2.in.handle, LSA_HANDLE_POLICY);
3120 talloc_steal(mem_ctx, h);
3122 r2.in.num_names = r->in.num_names;
3123 r2.in.names = r->in.names;
3124 r2.in.sids = r->in.sids;
3125 r2.in.count = r->in.count;
3126 r2.in.unknown1 = r->in.unknown1;
3127 r2.in.unknown2 = r->in.unknown2;
3128 r2.out.domains = r->out.domains;
3129 r2.out.sids = r->out.sids;
3130 r2.out.count = r->out.count;
3132 status = lsa_LookupNames3(dce_call, mem_ctx, &r2);
3133 if (dce_call->fault_code != 0) {
3137 r->out.domains = r2.out.domains;
3138 r->out.sids = r2.out.sids;
3139 r->out.count = r2.out.count;
3146 static NTSTATUS lsa_LookupNames2(struct dcesrv_call_state *dce_call,
3147 TALLOC_CTX *mem_ctx,
3148 struct lsa_LookupNames2 *r)
3150 struct lsa_policy_state *state;
3151 struct dcesrv_handle *h;
3153 NTSTATUS status = NT_STATUS_OK;
3155 r->out.domains = NULL;
3157 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3161 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
3162 if (r->out.domains == NULL) {
3163 return NT_STATUS_NO_MEMORY;
3166 r->out.sids = talloc_zero(mem_ctx, struct lsa_TransSidArray2);
3167 if (r->out.sids == NULL) {
3168 return NT_STATUS_NO_MEMORY;
3173 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid2,
3175 if (r->out.sids->sids == NULL) {
3176 return NT_STATUS_NO_MEMORY;
3179 for (i=0;i<r->in.num_names;i++) {
3180 const char *name = r->in.names[i].string;
3181 struct dom_sid *sid;
3182 uint32_t atype, rtype, sid_index;
3185 r->out.sids->count++;
3188 r->out.sids->sids[i].sid_type = SID_NAME_UNKNOWN;
3189 r->out.sids->sids[i].rid = 0xFFFFFFFF;
3190 r->out.sids->sids[i].sid_index = 0xFFFFFFFF;
3191 r->out.sids->sids[i].unknown = 0;
3193 status2 = lsa_lookup_name(state, mem_ctx, name, &sid, &atype);
3194 if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
3195 status = STATUS_SOME_UNMAPPED;
3199 rtype = samdb_atype_map(atype);
3200 if (rtype == SID_NAME_UNKNOWN) {
3201 status = STATUS_SOME_UNMAPPED;
3205 status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
3206 if (!NT_STATUS_IS_OK(status2)) {
3210 r->out.sids->sids[i].sid_type = rtype;
3211 r->out.sids->sids[i].rid = sid->sub_auths[sid->num_auths-1];
3212 r->out.sids->sids[i].sid_index = sid_index;
3213 r->out.sids->sids[i].unknown = 0;
3222 static NTSTATUS lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3223 struct lsa_LookupNames *r)
3225 struct lsa_LookupNames2 r2;
3229 r2.in.handle = r->in.handle;
3230 r2.in.num_names = r->in.num_names;
3231 r2.in.names = r->in.names;
3233 r2.in.level = r->in.level;
3234 r2.in.count = r->in.count;
3237 r2.out.count = r->out.count;
3239 status = lsa_LookupNames2(dce_call, mem_ctx, &r2);
3240 if (dce_call->fault_code != 0) {
3244 r->out.domains = r2.out.domains;
3245 r->out.sids = talloc(mem_ctx, struct lsa_TransSidArray);
3246 if (r->out.sids == NULL) {
3247 return NT_STATUS_NO_MEMORY;
3249 r->out.sids->count = r2.out.sids->count;
3250 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid,
3251 r->out.sids->count);
3252 if (r->out.sids->sids == NULL) {
3253 return NT_STATUS_NO_MEMORY;
3255 for (i=0;i<r->out.sids->count;i++) {
3256 r->out.sids->sids[i].sid_type = r2.out.sids->sids[i].sid_type;
3257 r->out.sids->sids[i].rid = r2.out.sids->sids[i].rid;
3258 r->out.sids->sids[i].sid_index = r2.out.sids->sids[i].sid_index;
3267 static NTSTATUS lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3268 struct lsa_CREDRWRITE *r)
3270 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3277 static NTSTATUS lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3278 struct lsa_CREDRREAD *r)
3280 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3287 static NTSTATUS lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3288 struct lsa_CREDRENUMERATE *r)
3290 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3295 lsa_CREDRWRITEDOMAINCREDENTIALS
3297 static NTSTATUS lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3298 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3300 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3305 lsa_CREDRREADDOMAINCREDENTIALS
3307 static NTSTATUS lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3308 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3310 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3317 static NTSTATUS lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3318 struct lsa_CREDRDELETE *r)
3320 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3325 lsa_CREDRGETTARGETINFO
3327 static NTSTATUS lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3328 struct lsa_CREDRGETTARGETINFO *r)
3330 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3335 lsa_CREDRPROFILELOADED
3337 static NTSTATUS lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3338 struct lsa_CREDRPROFILELOADED *r)
3340 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3345 lsa_CREDRGETSESSIONTYPES
3347 static NTSTATUS lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3348 struct lsa_CREDRGETSESSIONTYPES *r)
3350 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3355 lsa_LSARREGISTERAUDITEVENT
3357 static NTSTATUS lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3358 struct lsa_LSARREGISTERAUDITEVENT *r)
3360 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3365 lsa_LSARGENAUDITEVENT
3367 static NTSTATUS lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3368 struct lsa_LSARGENAUDITEVENT *r)
3370 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3375 lsa_LSARUNREGISTERAUDITEVENT
3377 static NTSTATUS lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3378 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3380 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3385 lsa_LSARQUERYFORESTTRUSTINFORMATION
3387 static NTSTATUS lsa_LSARQUERYFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3388 struct lsa_LSARQUERYFORESTTRUSTINFORMATION *r)
3390 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3395 lsa_LSARSETFORESTTRUSTINFORMATION
3397 static NTSTATUS lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3398 struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
3400 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3407 static NTSTATUS lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3408 struct lsa_CREDRRENAME *r)
3410 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3416 lsa_LSAROPENPOLICYSCE
3418 static NTSTATUS lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3419 struct lsa_LSAROPENPOLICYSCE *r)
3421 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3426 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
3428 static NTSTATUS lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3429 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
3431 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3436 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
3438 static NTSTATUS lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3439 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
3441 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3446 lsa_LSARADTREPORTSECURITYEVENT
3448 static NTSTATUS lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3449 struct lsa_LSARADTREPORTSECURITYEVENT *r)
3451 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3455 /* include the generated boilerplate */
3456 #include "librpc/gen_ndr/ndr_lsa_s.c"
3460 /*****************************************
3461 NOTE! The remaining calls below were
3462 removed in w2k3, so the DCESRV_FAULT()
3463 replies are the correct implementation. Do
3464 not try and fill these in with anything else
3465 ******************************************/
3468 dssetup_DsRoleDnsNameToFlatName
3470 static WERROR dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3471 struct dssetup_DsRoleDnsNameToFlatName *r)
3473 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3478 dssetup_DsRoleDcAsDc
3480 static WERROR dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3481 struct dssetup_DsRoleDcAsDc *r)
3483 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3488 dssetup_DsRoleDcAsReplica
3490 static WERROR dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3491 struct dssetup_DsRoleDcAsReplica *r)
3493 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3498 dssetup_DsRoleDemoteDc
3500 static WERROR dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3501 struct dssetup_DsRoleDemoteDc *r)
3503 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3508 dssetup_DsRoleGetDcOperationProgress
3510 static WERROR dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3511 struct dssetup_DsRoleGetDcOperationProgress *r)
3513 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3518 dssetup_DsRoleGetDcOperationResults
3520 static WERROR dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3521 struct dssetup_DsRoleGetDcOperationResults *r)
3523 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3528 dssetup_DsRoleCancel
3530 static WERROR dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3531 struct dssetup_DsRoleCancel *r)
3533 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3538 dssetup_DsRoleServerSaveStateForUpgrade
3540 static WERROR dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3541 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
3543 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3548 dssetup_DsRoleUpgradeDownlevelServer
3550 static WERROR dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3551 struct dssetup_DsRoleUpgradeDownlevelServer *r)
3553 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3558 dssetup_DsRoleAbortDownlevelServerUpgrade
3560 static WERROR dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3561 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
3563 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3567 /* include the generated boilerplate */
3568 #include "librpc/gen_ndr/ndr_dssetup_s.c"
3570 NTSTATUS dcerpc_server_lsa_init(void)
3574 ret = dcerpc_server_dssetup_init();
3575 if (!NT_STATUS_IS_OK(ret)) {
3578 ret = dcerpc_server_lsarpc_init();
3579 if (!NT_STATUS_IS_OK(ret)) {