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[] = {
291 state = talloc(mem_ctx, struct lsa_policy_state);
293 return NT_STATUS_NO_MEMORY;
296 /* make sure the sam database is accessible */
297 state->sam_ldb = samdb_connect(state, dce_call->conn->auth_state.session_info);
298 if (state->sam_ldb == NULL) {
299 return NT_STATUS_INVALID_SYSTEM_SERVICE;
302 partitions_basedn = samdb_partitions_dn(state->sam_ldb, mem_ctx);
304 state->sidmap = sidmap_open(state);
305 if (state->sidmap == NULL) {
306 return NT_STATUS_INVALID_SYSTEM_SERVICE;
309 /* work out the domain_dn - useful for so many calls its worth
311 state->domain_dn = samdb_base_dn(state->sam_ldb);
312 if (!state->domain_dn) {
313 return NT_STATUS_NO_MEMORY;
316 ret = ldb_search(state->sam_ldb, state->domain_dn, LDB_SCOPE_BASE, NULL, dom_attrs, &dom_res);
318 if (ret != LDB_SUCCESS) {
319 return NT_STATUS_INVALID_SYSTEM_SERVICE;
321 talloc_steal(state, dom_res);
322 if (dom_res->count != 1) {
323 return NT_STATUS_NO_SUCH_DOMAIN;
326 state->domain_sid = samdb_result_dom_sid(state, dom_res->msgs[0], "objectSid");
327 if (!state->domain_sid) {
328 return NT_STATUS_NO_SUCH_DOMAIN;
331 state->domain_guid = samdb_result_guid(dom_res->msgs[0], "objectGUID");
332 if (!state->domain_sid) {
333 return NT_STATUS_NO_SUCH_DOMAIN;
336 state->mixed_domain = ldb_msg_find_attr_as_uint(dom_res->msgs[0], "nTMixedDomain", 0);
338 talloc_free(dom_res);
340 ref_filter = talloc_asprintf(state, "(&(objectclass=crossRef)(ncName=%s))",
341 ldb_dn_get_linearized(state->domain_dn));
343 return NT_STATUS_NO_MEMORY;
346 ret = ldb_search(state->sam_ldb, partitions_basedn, LDB_SCOPE_SUBTREE, ref_filter, ref_attrs, &ref_res);
347 talloc_steal(state, ref_res);
348 talloc_free(ref_filter);
350 if (ret != LDB_SUCCESS) {
351 return NT_STATUS_INVALID_SYSTEM_SERVICE;
353 if (ref_res->count != 1) {
354 return NT_STATUS_NO_SUCH_DOMAIN;
357 state->domain_name = ldb_msg_find_attr_as_string(ref_res->msgs[0], "nETBIOSName", NULL);
358 if (!state->domain_name) {
359 return NT_STATUS_NO_SUCH_DOMAIN;
361 talloc_steal(state, state->domain_name);
363 state->domain_dns = ldb_msg_find_attr_as_string(ref_res->msgs[0], "dnsRoot", NULL);
364 if (!state->domain_dns) {
365 return NT_STATUS_NO_SUCH_DOMAIN;
367 talloc_steal(state, state->domain_dns);
369 talloc_free(ref_res);
371 /* work out the builtin_dn - useful for so many calls its worth
373 state->builtin_dn = samdb_search_dn(state->sam_ldb, state, state->domain_dn, "(objectClass=builtinDomain)");
374 if (!state->builtin_dn) {
375 return NT_STATUS_NO_SUCH_DOMAIN;
378 /* work out the system_dn - useful for so many calls its worth
380 state->system_dn = samdb_search_dn(state->sam_ldb, state,
381 state->domain_dn, "(&(objectClass=container)(cn=System))");
382 if (!state->system_dn) {
383 return NT_STATUS_NO_SUCH_DOMAIN;
386 state->builtin_sid = dom_sid_parse_talloc(state, SID_BUILTIN);
387 if (!state->builtin_sid) {
388 return NT_STATUS_NO_SUCH_DOMAIN;
397 dssetup_DsRoleGetPrimaryDomainInformation
399 This is not an LSA call, but is the only call left on the DSSETUP
400 pipe (after the pipe was truncated), and needs lsa_get_policy_state
402 static WERROR dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state *dce_call,
404 struct dssetup_DsRoleGetPrimaryDomainInformation *r)
406 union dssetup_DsRoleInfo *info;
408 info = talloc(mem_ctx, union dssetup_DsRoleInfo);
409 W_ERROR_HAVE_NO_MEMORY(info);
411 switch (r->in.level) {
412 case DS_ROLE_BASIC_INFORMATION:
414 enum dssetup_DsRole role = DS_ROLE_STANDALONE_SERVER;
416 const char *domain = NULL;
417 const char *dns_domain = NULL;
418 const char *forest = NULL;
419 struct GUID domain_guid;
420 struct lsa_policy_state *state;
422 NTSTATUS status = lsa_get_policy_state(dce_call, mem_ctx, &state);
423 if (!NT_STATUS_IS_OK(status)) {
424 return ntstatus_to_werror(status);
427 ZERO_STRUCT(domain_guid);
429 switch (lp_server_role()) {
430 case ROLE_STANDALONE:
431 role = DS_ROLE_STANDALONE_SERVER;
433 case ROLE_DOMAIN_MEMBER:
434 role = DS_ROLE_MEMBER_SERVER;
436 case ROLE_DOMAIN_BDC:
437 role = DS_ROLE_BACKUP_DC;
439 case ROLE_DOMAIN_PDC:
440 role = DS_ROLE_PRIMARY_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_BDC:
455 case ROLE_DOMAIN_PDC:
456 flags = DS_ROLE_PRIMARY_DS_RUNNING;
458 if (state->mixed_domain == 1) {
459 flags |= DS_ROLE_PRIMARY_DS_MIXED_MODE;
462 domain = state->domain_name;
463 dns_domain = state->domain_dns;
464 forest = state->domain_dns;
466 domain_guid = state->domain_guid;
467 flags |= DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT;
471 info->basic.role = role;
472 info->basic.flags = flags;
473 info->basic.domain = domain;
474 info->basic.dns_domain = dns_domain;
475 info->basic.forest = forest;
476 info->basic.domain_guid = domain_guid;
481 case DS_ROLE_UPGRADE_STATUS:
483 info->upgrade.upgrading = DS_ROLE_NOT_UPGRADING;
484 info->upgrade.previous_role = DS_ROLE_PREVIOUS_UNKNOWN;
489 case DS_ROLE_OP_STATUS:
491 info->opstatus.status = DS_ROLE_OP_IDLE;
497 return WERR_INVALID_PARAM;
500 return WERR_INVALID_PARAM;
506 static NTSTATUS lsa_OpenPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
507 struct lsa_OpenPolicy2 *r)
510 struct lsa_policy_state *state;
511 struct dcesrv_handle *handle;
513 ZERO_STRUCTP(r->out.handle);
515 status = lsa_get_policy_state(dce_call, mem_ctx, &state);
516 if (!NT_STATUS_IS_OK(status)) {
520 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_POLICY);
522 return NT_STATUS_NO_MEMORY;
525 handle->data = talloc_steal(handle, state);
527 state->access_mask = r->in.access_mask;
528 state->handle = handle;
529 *r->out.handle = handle->wire_handle;
531 /* note that we have completely ignored the attr element of
532 the OpenPolicy. As far as I can tell, this is what w2k3
540 a wrapper around lsa_OpenPolicy2
542 static NTSTATUS lsa_OpenPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
543 struct lsa_OpenPolicy *r)
545 struct lsa_OpenPolicy2 r2;
547 r2.in.system_name = NULL;
548 r2.in.attr = r->in.attr;
549 r2.in.access_mask = r->in.access_mask;
550 r2.out.handle = r->out.handle;
552 return lsa_OpenPolicy2(dce_call, mem_ctx, &r2);
559 fill in the AccountDomain info
561 static NTSTATUS lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
562 struct lsa_DomainInfo *info)
564 info->name.string = state->domain_name;
565 info->sid = state->domain_sid;
571 fill in the DNS domain info
573 static NTSTATUS lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
574 struct lsa_DnsDomainInfo *info)
576 info->name.string = state->domain_name;
577 info->sid = state->domain_sid;
578 info->dns_domain.string = state->domain_dns;
579 info->dns_forest.string = state->domain_dns;
580 info->domain_guid = state->domain_guid;
588 static NTSTATUS lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
589 struct lsa_QueryInfoPolicy2 *r)
591 struct lsa_policy_state *state;
592 struct dcesrv_handle *h;
596 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
600 r->out.info = talloc(mem_ctx, union lsa_PolicyInformation);
602 return NT_STATUS_NO_MEMORY;
605 ZERO_STRUCTP(r->out.info);
607 switch (r->in.level) {
608 case LSA_POLICY_INFO_DOMAIN:
609 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
610 return lsa_info_AccountDomain(state, mem_ctx, &r->out.info->account_domain);
612 case LSA_POLICY_INFO_DNS:
613 return lsa_info_DNS(state, mem_ctx, &r->out.info->dns);
616 return NT_STATUS_INVALID_INFO_CLASS;
622 static NTSTATUS lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
623 struct lsa_QueryInfoPolicy *r)
625 struct lsa_QueryInfoPolicy2 r2;
628 r2.in.handle = r->in.handle;
629 r2.in.level = r->in.level;
631 status = lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
633 r->out.info = r2.out.info;
641 static NTSTATUS lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
642 struct lsa_SetInfoPolicy *r)
644 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
651 static NTSTATUS lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
652 struct lsa_ClearAuditLog *r)
654 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
661 static NTSTATUS lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
662 struct lsa_CreateAccount *r)
664 struct lsa_account_state *astate;
666 struct lsa_policy_state *state;
667 struct dcesrv_handle *h, *ah;
669 ZERO_STRUCTP(r->out.acct_handle);
671 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
675 astate = talloc(dce_call->conn, struct lsa_account_state);
676 if (astate == NULL) {
677 return NT_STATUS_NO_MEMORY;
680 astate->account_sid = dom_sid_dup(astate, r->in.sid);
681 if (astate->account_sid == NULL) {
683 return NT_STATUS_NO_MEMORY;
686 astate->policy = talloc_reference(astate, state);
687 astate->access_mask = r->in.access_mask;
689 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
692 return NT_STATUS_NO_MEMORY;
695 ah->data = talloc_steal(ah, astate);
697 *r->out.acct_handle = ah->wire_handle;
706 static NTSTATUS lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
707 struct lsa_EnumAccounts *r)
709 struct dcesrv_handle *h;
710 struct lsa_policy_state *state;
712 struct ldb_message **res;
713 const char * const attrs[] = { "objectSid", NULL};
716 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
720 /* NOTE: This call must only return accounts that have at least
723 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
724 "(&(objectSid=*)(privilege=*))");
726 return NT_STATUS_NO_SUCH_USER;
729 if (*r->in.resume_handle >= ret) {
730 return NT_STATUS_NO_MORE_ENTRIES;
733 count = ret - *r->in.resume_handle;
734 if (count > r->in.num_entries) {
735 count = r->in.num_entries;
739 return NT_STATUS_NO_MORE_ENTRIES;
742 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, count);
743 if (r->out.sids->sids == NULL) {
744 return NT_STATUS_NO_MEMORY;
747 for (i=0;i<count;i++) {
748 r->out.sids->sids[i].sid =
749 samdb_result_dom_sid(r->out.sids->sids,
750 res[i + *r->in.resume_handle],
752 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
755 r->out.sids->num_sids = count;
756 *r->out.resume_handle = count + *r->in.resume_handle;
764 lsa_CreateTrustedDomainEx2
766 static NTSTATUS lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
768 struct lsa_CreateTrustedDomainEx2 *r)
770 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
774 lsa_CreateTrustedDomainEx
776 static NTSTATUS lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
778 struct lsa_CreateTrustedDomainEx *r)
780 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
784 lsa_CreateTrustedDomain
786 static NTSTATUS lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
787 struct lsa_CreateTrustedDomain *r)
789 struct dcesrv_handle *policy_handle;
790 struct lsa_policy_state *policy_state;
791 struct lsa_trusted_domain_state *trusted_domain_state;
792 struct dcesrv_handle *handle;
793 struct ldb_message **msgs, *msg;
794 const char *attrs[] = {
800 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
801 ZERO_STRUCTP(r->out.trustdom_handle);
803 policy_state = policy_handle->data;
805 if (!r->in.info->name.string) {
806 return NT_STATUS_INVALID_PARAMETER;
808 name = r->in.info->name.string;
810 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
811 if (!trusted_domain_state) {
812 return NT_STATUS_NO_MEMORY;
814 trusted_domain_state->policy = policy_state;
816 msg = ldb_msg_new(mem_ctx);
818 return NT_STATUS_NO_MEMORY;
821 /* search for the trusted_domain record */
822 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
823 mem_ctx, policy_state->system_dn, &msgs, attrs,
824 "(&(cn=%s)(objectclass=trustedDomain))",
825 ldb_binary_encode_string(mem_ctx, r->in.info->name.string));
827 return NT_STATUS_OBJECT_NAME_COLLISION;
830 if (ret < 0 || ret > 1) {
831 DEBUG(0,("Found %d records matching DN %s\n", ret,
832 ldb_dn_get_linearized(policy_state->system_dn)));
833 return NT_STATUS_INTERNAL_DB_CORRUPTION;
836 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
837 if ( ! ldb_dn_add_child_fmt(msg->dn, "sn=%s", r->in.info->name.string)) {
838 return NT_STATUS_NO_MEMORY;
841 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "cn", name);
842 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "flatname", name);
844 if (r->in.info->sid) {
845 const char *sid_string = dom_sid_string(mem_ctx, r->in.info->sid);
847 return NT_STATUS_NO_MEMORY;
850 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "securityIdentifier", sid_string);
853 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "objectClass", "trustedDomain");
855 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
857 /* create the trusted_domain */
858 ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg);
859 if (ret != LDB_SUCCESS) {
860 DEBUG(0,("Failed to create trusted_domain record %s: %s\n",
861 ldb_dn_get_linearized(msg->dn), ldb_errstring(trusted_domain_state->policy->sam_ldb)));
862 return NT_STATUS_INTERNAL_DB_CORRUPTION;
865 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
867 return NT_STATUS_NO_MEMORY;
870 handle->data = talloc_steal(handle, trusted_domain_state);
872 trusted_domain_state->access_mask = r->in.access_mask;
873 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
875 *r->out.trustdom_handle = handle->wire_handle;
881 lsa_OpenTrustedDomain
883 static NTSTATUS lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
884 struct lsa_OpenTrustedDomain *r)
886 struct dcesrv_handle *policy_handle;
888 struct lsa_policy_state *policy_state;
889 struct lsa_trusted_domain_state *trusted_domain_state;
890 struct dcesrv_handle *handle;
891 struct ldb_message **msgs;
892 const char *attrs[] = {
896 const char *sid_string;
899 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
900 ZERO_STRUCTP(r->out.trustdom_handle);
901 policy_state = policy_handle->data;
903 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
904 if (!trusted_domain_state) {
905 return NT_STATUS_NO_MEMORY;
907 trusted_domain_state->policy = policy_state;
909 sid_string = dom_sid_string(mem_ctx, r->in.sid);
911 return NT_STATUS_NO_MEMORY;
914 /* search for the trusted_domain record */
915 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
916 mem_ctx, policy_state->system_dn, &msgs, attrs,
917 "(&(securityIdentifier=%s)(objectclass=trustedDomain))",
920 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
924 DEBUG(0,("Found %d records matching DN %s\n", ret,
925 ldb_dn_get_linearized(policy_state->system_dn)));
926 return NT_STATUS_INTERNAL_DB_CORRUPTION;
929 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
931 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
933 return NT_STATUS_NO_MEMORY;
936 handle->data = talloc_steal(handle, trusted_domain_state);
938 trusted_domain_state->access_mask = r->in.access_mask;
939 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
941 *r->out.trustdom_handle = handle->wire_handle;
948 lsa_OpenTrustedDomainByName
950 static NTSTATUS lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
952 struct lsa_OpenTrustedDomainByName *r)
954 struct dcesrv_handle *policy_handle;
956 struct lsa_policy_state *policy_state;
957 struct lsa_trusted_domain_state *trusted_domain_state;
958 struct dcesrv_handle *handle;
959 struct ldb_message **msgs;
960 const char *attrs[] = {
966 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
967 ZERO_STRUCTP(r->out.trustdom_handle);
968 policy_state = policy_handle->data;
970 if (!r->in.name.string) {
971 return NT_STATUS_INVALID_PARAMETER;
974 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
975 if (!trusted_domain_state) {
976 return NT_STATUS_NO_MEMORY;
978 trusted_domain_state->policy = policy_state;
980 /* search for the trusted_domain record */
981 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
982 mem_ctx, policy_state->system_dn, &msgs, attrs,
983 "(&(flatname=%s)(objectclass=trustedDomain))",
984 ldb_binary_encode_string(mem_ctx, r->in.name.string));
986 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
990 DEBUG(0,("Found %d records matching DN %s\n", ret,
991 ldb_dn_get_linearized(policy_state->system_dn)));
992 return NT_STATUS_INTERNAL_DB_CORRUPTION;
995 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
997 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
999 return NT_STATUS_NO_MEMORY;
1002 handle->data = talloc_steal(handle, trusted_domain_state);
1004 trusted_domain_state->access_mask = r->in.access_mask;
1005 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1007 *r->out.trustdom_handle = handle->wire_handle;
1009 return NT_STATUS_OK;
1015 lsa_SetTrustedDomainInfo
1017 static NTSTATUS lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1018 struct lsa_SetTrustedDomainInfo *r)
1020 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1026 lsa_SetInfomrationTrustedDomain
1028 static NTSTATUS lsa_SetInformationTrustedDomain(struct dcesrv_call_state *dce_call,
1029 TALLOC_CTX *mem_ctx,
1030 struct lsa_SetInformationTrustedDomain *r)
1032 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1037 lsa_DeleteTrustedDomain
1039 static NTSTATUS lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1040 struct lsa_DeleteTrustedDomain *r)
1043 struct lsa_OpenTrustedDomain open;
1044 struct lsa_Delete delete;
1045 struct dcesrv_handle *h;
1047 open.in.handle = r->in.handle;
1048 open.in.sid = r->in.dom_sid;
1049 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1050 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1051 if (!open.out.trustdom_handle) {
1052 return NT_STATUS_NO_MEMORY;
1054 status = lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
1055 if (!NT_STATUS_IS_OK(status)) {
1059 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1060 talloc_steal(mem_ctx, h);
1062 delete.in.handle = open.out.trustdom_handle;
1063 status = lsa_Delete(dce_call, mem_ctx, &delete);
1064 if (!NT_STATUS_IS_OK(status)) {
1067 return NT_STATUS_OK;
1070 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx,
1071 struct ldb_message *msg,
1072 struct lsa_TrustDomainInfoInfoEx *info_ex)
1074 info_ex->domain_name.string
1075 = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
1076 info_ex->netbios_name.string
1077 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1079 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1080 info_ex->trust_direction
1081 = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
1083 = ldb_msg_find_attr_as_int(msg, "trustType", 0);
1084 info_ex->trust_attributes
1085 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);
1086 return NT_STATUS_OK;
1090 lsa_QueryTrustedDomainInfo
1092 static NTSTATUS lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1093 struct lsa_QueryTrustedDomainInfo *r)
1095 struct dcesrv_handle *h;
1096 struct lsa_trusted_domain_state *trusted_domain_state;
1097 struct ldb_message *msg;
1099 struct ldb_message **res;
1100 const char *attrs[] = {
1103 "securityIdentifier",
1110 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
1112 trusted_domain_state = h->data;
1114 /* pull all the user attributes */
1115 ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
1116 trusted_domain_state->trusted_domain_dn, &res, attrs);
1118 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1122 r->out.info = talloc(mem_ctx, union lsa_TrustedDomainInfo);
1124 return NT_STATUS_NO_MEMORY;
1126 switch (r->in.level) {
1127 case LSA_TRUSTED_DOMAIN_INFO_NAME:
1128 r->out.info->name.netbios_name.string
1129 = samdb_result_string(msg, "flatname", NULL);
1131 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1132 r->out.info->posix_offset.posix_offset
1133 = samdb_result_uint(msg, "posixOffset", 0);
1135 #if 0 /* Win2k3 doesn't implement this */
1136 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
1137 r->out.info->info_basic.netbios_name.string
1138 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1139 r->out.info->info_basic.sid
1140 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1143 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1144 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->info_ex);
1146 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1147 ZERO_STRUCT(r->out.info->full_info);
1148 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->full_info.info_ex);
1150 case LSA_TRUSTED_DOMAIN_INFO_INFO_ALL:
1151 ZERO_STRUCT(r->out.info->info_all);
1152 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->info_all.info_ex);
1154 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS_INFO:
1155 case LSA_TRUSTED_DOMAIN_INFO_11:
1156 /* oops, we don't want to return the info after all */
1157 talloc_free(r->out.info);
1159 return NT_STATUS_INVALID_PARAMETER;
1161 /* oops, we don't want to return the info after all */
1162 talloc_free(r->out.info);
1164 return NT_STATUS_INVALID_INFO_CLASS;
1167 return NT_STATUS_OK;
1172 lsa_QueryTrustedDomainInfoBySid
1174 static NTSTATUS lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1175 struct lsa_QueryTrustedDomainInfoBySid *r)
1178 struct lsa_OpenTrustedDomain open;
1179 struct lsa_QueryTrustedDomainInfo query;
1180 struct dcesrv_handle *h;
1181 open.in.handle = r->in.handle;
1182 open.in.sid = r->in.dom_sid;
1183 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1184 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1185 if (!open.out.trustdom_handle) {
1186 return NT_STATUS_NO_MEMORY;
1188 status = lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
1189 if (!NT_STATUS_IS_OK(status)) {
1193 /* Ensure this handle goes away at the end of this call */
1194 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1195 talloc_steal(mem_ctx, h);
1197 query.in.trustdom_handle = open.out.trustdom_handle;
1198 query.in.level = r->in.level;
1199 status = lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1200 if (!NT_STATUS_IS_OK(status)) {
1204 r->out.info = query.out.info;
1205 return NT_STATUS_OK;
1209 lsa_SetTrustedDomainInfoByName
1211 static NTSTATUS lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1212 TALLOC_CTX *mem_ctx,
1213 struct lsa_SetTrustedDomainInfoByName *r)
1215 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1219 lsa_QueryTrustedDomainInfoByName
1221 static NTSTATUS lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1222 TALLOC_CTX *mem_ctx,
1223 struct lsa_QueryTrustedDomainInfoByName *r)
1226 struct lsa_OpenTrustedDomainByName open;
1227 struct lsa_QueryTrustedDomainInfo query;
1228 struct dcesrv_handle *h;
1229 open.in.handle = r->in.handle;
1230 open.in.name = r->in.trusted_domain;
1231 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1232 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1233 if (!open.out.trustdom_handle) {
1234 return NT_STATUS_NO_MEMORY;
1236 status = lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &open);
1237 if (!NT_STATUS_IS_OK(status)) {
1241 /* Ensure this handle goes away at the end of this call */
1242 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1243 talloc_steal(mem_ctx, h);
1245 query.in.trustdom_handle = open.out.trustdom_handle;
1246 query.in.level = r->in.level;
1247 status = lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1248 if (!NT_STATUS_IS_OK(status)) {
1252 r->out.info = query.out.info;
1253 return NT_STATUS_OK;
1257 lsa_CloseTrustedDomainEx
1259 static NTSTATUS lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
1260 TALLOC_CTX *mem_ctx,
1261 struct lsa_CloseTrustedDomainEx *r)
1263 /* The result of a bad hair day from an IDL programmer? Not
1264 * implmented in Win2k3. You should always just lsa_Close
1266 return NT_STATUS_NOT_IMPLEMENTED;
1271 comparison function for sorting lsa_DomainInformation array
1273 static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
1275 return strcasecmp_m(e1->name.string, e2->name.string);
1281 static NTSTATUS lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1282 struct lsa_EnumTrustDom *r)
1284 struct dcesrv_handle *policy_handle;
1285 struct lsa_DomainInfo *entries;
1286 struct lsa_policy_state *policy_state;
1287 struct ldb_message **domains;
1288 const char *attrs[] = {
1290 "securityIdentifier",
1297 *r->out.resume_handle = 0;
1299 r->out.domains->domains = NULL;
1300 r->out.domains->count = 0;
1302 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1304 policy_state = policy_handle->data;
1306 /* search for all users in this domain. This could possibly be cached and
1307 resumed based on resume_key */
1308 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1309 "objectclass=trustedDomain");
1311 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1313 if (count == 0 || r->in.max_size == 0) {
1314 return NT_STATUS_OK;
1317 /* convert to lsa_TrustInformation format */
1318 entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
1320 return NT_STATUS_NO_MEMORY;
1322 for (i=0;i<count;i++) {
1323 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
1324 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
1327 /* sort the results by name */
1328 qsort(entries, count, sizeof(*entries),
1329 (comparison_fn_t)compare_DomainInfo);
1331 if (*r->in.resume_handle >= count) {
1332 *r->out.resume_handle = -1;
1334 return NT_STATUS_NO_MORE_ENTRIES;
1337 /* return the rest, limit by max_size. Note that we
1338 use the w2k3 element size value of 60 */
1339 r->out.domains->count = count - *r->in.resume_handle;
1340 r->out.domains->count = MIN(r->out.domains->count,
1341 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
1343 r->out.domains->domains = entries + *r->in.resume_handle;
1344 r->out.domains->count = r->out.domains->count;
1346 if (r->out.domains->count < count - *r->in.resume_handle) {
1347 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1348 return STATUS_MORE_ENTRIES;
1351 return NT_STATUS_OK;
1355 comparison function for sorting lsa_DomainInformation array
1357 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
1359 return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
1363 lsa_EnumTrustedDomainsEx
1365 static NTSTATUS lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1366 struct lsa_EnumTrustedDomainsEx *r)
1368 struct dcesrv_handle *policy_handle;
1369 struct lsa_TrustDomainInfoInfoEx *entries;
1370 struct lsa_policy_state *policy_state;
1371 struct ldb_message **domains;
1372 const char *attrs[] = {
1375 "securityIdentifier",
1385 *r->out.resume_handle = 0;
1387 r->out.domains->domains = NULL;
1388 r->out.domains->count = 0;
1390 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1392 policy_state = policy_handle->data;
1394 /* search for all users in this domain. This could possibly be cached and
1395 resumed based on resume_key */
1396 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1397 "objectclass=trustedDomain");
1399 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1401 if (count == 0 || r->in.max_size == 0) {
1402 return NT_STATUS_OK;
1405 /* convert to lsa_DomainInformation format */
1406 entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
1408 return NT_STATUS_NO_MEMORY;
1410 for (i=0;i<count;i++) {
1411 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
1412 if (!NT_STATUS_IS_OK(nt_status)) {
1417 /* sort the results by name */
1418 qsort(entries, count, sizeof(*entries),
1419 (comparison_fn_t)compare_TrustDomainInfoInfoEx);
1421 if (*r->in.resume_handle >= count) {
1422 *r->out.resume_handle = -1;
1424 return NT_STATUS_NO_MORE_ENTRIES;
1427 /* return the rest, limit by max_size. Note that we
1428 use the w2k3 element size value of 60 */
1429 r->out.domains->count = count - *r->in.resume_handle;
1430 r->out.domains->count = MIN(r->out.domains->count,
1431 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
1433 r->out.domains->domains = entries + *r->in.resume_handle;
1434 r->out.domains->count = r->out.domains->count;
1436 if (r->out.domains->count < count - *r->in.resume_handle) {
1437 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1438 return STATUS_MORE_ENTRIES;
1441 return NT_STATUS_OK;
1446 return the authority name and authority sid, given a sid
1448 static NTSTATUS lsa_authority_name(struct lsa_policy_state *state,
1449 TALLOC_CTX *mem_ctx, struct dom_sid *sid,
1450 const char **authority_name,
1451 struct dom_sid **authority_sid)
1453 if (dom_sid_in_domain(state->domain_sid, sid)) {
1454 *authority_name = state->domain_name;
1455 *authority_sid = state->domain_sid;
1456 return NT_STATUS_OK;
1459 if (dom_sid_in_domain(state->builtin_sid, sid)) {
1460 *authority_name = "BUILTIN";
1461 *authority_sid = state->builtin_sid;
1462 return NT_STATUS_OK;
1465 *authority_sid = dom_sid_dup(mem_ctx, sid);
1466 if (*authority_sid == NULL) {
1467 return NT_STATUS_NO_MEMORY;
1469 (*authority_sid)->num_auths = 0;
1470 *authority_name = dom_sid_string(mem_ctx, *authority_sid);
1471 if (*authority_name == NULL) {
1472 return NT_STATUS_NO_MEMORY;
1475 return NT_STATUS_OK;
1479 add to the lsa_RefDomainList for LookupSids and LookupNames
1481 static NTSTATUS lsa_authority_list(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
1482 struct dom_sid *sid,
1483 struct lsa_RefDomainList *domains,
1484 uint32_t *sid_index)
1487 const char *authority_name;
1488 struct dom_sid *authority_sid;
1491 /* work out the authority name */
1492 status = lsa_authority_name(state, mem_ctx, sid,
1493 &authority_name, &authority_sid);
1494 if (!NT_STATUS_IS_OK(status)) {
1498 /* see if we've already done this authority name */
1499 for (i=0;i<domains->count;i++) {
1500 if (strcmp(authority_name, domains->domains[i].name.string) == 0) {
1502 return NT_STATUS_OK;
1506 domains->domains = talloc_realloc(domains,
1508 struct lsa_DomainInfo,
1510 if (domains->domains == NULL) {
1511 return NT_STATUS_NO_MEMORY;
1513 domains->domains[i].name.string = authority_name;
1514 domains->domains[i].sid = authority_sid;
1516 domains->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER * domains->count;
1519 return NT_STATUS_OK;
1523 lookup a name for 1 SID
1525 static NTSTATUS lsa_lookup_sid(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
1526 struct dom_sid *sid, const char *sid_str,
1527 const char **name, uint32_t *atype)
1530 struct ldb_message **res;
1531 const char * const attrs[] = { "sAMAccountName", "sAMAccountType", "name", NULL};
1534 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
1535 "objectSid=%s", ldap_encode_ndr_dom_sid(mem_ctx, sid));
1537 *name = ldb_msg_find_attr_as_string(res[0], "sAMAccountName", NULL);
1539 *name = ldb_msg_find_attr_as_string(res[0], "name", NULL);
1541 *name = talloc_strdup(mem_ctx, sid_str);
1542 NT_STATUS_HAVE_NO_MEMORY(*name);
1546 *atype = samdb_result_uint(res[0], "sAMAccountType", 0);
1548 return NT_STATUS_OK;
1551 status = sidmap_allocated_sid_lookup(state->sidmap, mem_ctx, sid, name, atype);
1560 static NTSTATUS lsa_LookupSids2(struct dcesrv_call_state *dce_call,
1561 TALLOC_CTX *mem_ctx,
1562 struct lsa_LookupSids2 *r)
1564 struct lsa_policy_state *state;
1566 NTSTATUS status = NT_STATUS_OK;
1568 r->out.domains = NULL;
1570 status = lsa_get_policy_state(dce_call, mem_ctx, &state);
1571 if (!NT_STATUS_IS_OK(status)) {
1575 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
1576 if (r->out.domains == NULL) {
1577 return NT_STATUS_NO_MEMORY;
1580 r->out.names = talloc_zero(mem_ctx, struct lsa_TransNameArray2);
1581 if (r->out.names == NULL) {
1582 return NT_STATUS_NO_MEMORY;
1587 r->out.names->names = talloc_array(r->out.names, struct lsa_TranslatedName2,
1588 r->in.sids->num_sids);
1589 if (r->out.names->names == NULL) {
1590 return NT_STATUS_NO_MEMORY;
1593 for (i=0;i<r->in.sids->num_sids;i++) {
1594 struct dom_sid *sid = r->in.sids->sids[i].sid;
1595 char *sid_str = dom_sid_string(mem_ctx, sid);
1597 uint32_t atype, rtype, sid_index;
1600 r->out.names->count++;
1603 r->out.names->names[i].sid_type = SID_NAME_UNKNOWN;
1604 r->out.names->names[i].name.string = sid_str;
1605 r->out.names->names[i].sid_index = 0xFFFFFFFF;
1606 r->out.names->names[i].unknown = 0;
1608 if (sid_str == NULL) {
1609 r->out.names->names[i].name.string = "(SIDERROR)";
1610 status = STATUS_SOME_UNMAPPED;
1614 /* work out the authority name */
1615 status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
1616 if (!NT_STATUS_IS_OK(status2)) {
1620 status2 = lsa_lookup_sid(state, mem_ctx, sid, sid_str,
1622 if (!NT_STATUS_IS_OK(status2)) {
1623 status = STATUS_SOME_UNMAPPED;
1627 rtype = samdb_atype_map(atype);
1628 if (rtype == SID_NAME_UNKNOWN) {
1629 status = STATUS_SOME_UNMAPPED;
1633 r->out.names->names[i].sid_type = rtype;
1634 r->out.names->names[i].name.string = name;
1635 r->out.names->names[i].sid_index = sid_index;
1636 r->out.names->names[i].unknown = 0;
1646 Identical to LookupSids2, but doesn't take a policy handle
1649 static NTSTATUS lsa_LookupSids3(struct dcesrv_call_state *dce_call,
1650 TALLOC_CTX *mem_ctx,
1651 struct lsa_LookupSids3 *r)
1653 struct lsa_LookupSids2 r2;
1654 struct lsa_OpenPolicy2 pol;
1656 struct dcesrv_handle *h;
1658 /* No policy handle on the wire, so make one up here */
1659 r2.in.handle = talloc(mem_ctx, struct policy_handle);
1660 if (!r2.in.handle) {
1661 return NT_STATUS_NO_MEMORY;
1664 pol.out.handle = r2.in.handle;
1665 pol.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1667 pol.in.system_name = NULL;
1668 status = lsa_OpenPolicy2(dce_call, mem_ctx, &pol);
1669 if (!NT_STATUS_IS_OK(status)) {
1673 /* ensure this handle goes away at the end of this call */
1674 DCESRV_PULL_HANDLE(h, r2.in.handle, LSA_HANDLE_POLICY);
1675 talloc_steal(mem_ctx, h);
1677 r2.in.sids = r->in.sids;
1678 r2.in.names = r->in.names;
1679 r2.in.level = r->in.level;
1680 r2.in.count = r->in.count;
1681 r2.in.unknown1 = r->in.unknown1;
1682 r2.in.unknown2 = r->in.unknown2;
1683 r2.out.count = r->out.count;
1684 r2.out.names = r->out.names;
1686 status = lsa_LookupSids2(dce_call, mem_ctx, &r2);
1687 if (dce_call->fault_code != 0) {
1691 r->out.domains = r2.out.domains;
1692 r->out.names = r2.out.names;
1693 r->out.count = r2.out.count;
1702 static NTSTATUS lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1703 struct lsa_LookupSids *r)
1705 struct lsa_LookupSids2 r2;
1709 r2.in.handle = r->in.handle;
1710 r2.in.sids = r->in.sids;
1712 r2.in.level = r->in.level;
1713 r2.in.count = r->in.count;
1716 r2.out.count = r->out.count;
1717 r2.out.names = NULL;
1719 status = lsa_LookupSids2(dce_call, mem_ctx, &r2);
1720 if (dce_call->fault_code != 0) {
1724 r->out.domains = r2.out.domains;
1725 if (!r2.out.names) {
1726 r->out.names = NULL;
1730 r->out.names = talloc(mem_ctx, struct lsa_TransNameArray);
1731 if (r->out.names == NULL) {
1732 return NT_STATUS_NO_MEMORY;
1734 r->out.names->count = r2.out.names->count;
1735 r->out.names->names = talloc_array(r->out.names, struct lsa_TranslatedName,
1736 r->out.names->count);
1737 if (r->out.names->names == NULL) {
1738 return NT_STATUS_NO_MEMORY;
1740 for (i=0;i<r->out.names->count;i++) {
1741 r->out.names->names[i].sid_type = r2.out.names->names[i].sid_type;
1742 r->out.names->names[i].name.string = r2.out.names->names[i].name.string;
1743 r->out.names->names[i].sid_index = r2.out.names->names[i].sid_index;
1753 static NTSTATUS lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1754 struct lsa_OpenAccount *r)
1756 struct dcesrv_handle *h, *ah;
1757 struct lsa_policy_state *state;
1758 struct lsa_account_state *astate;
1760 ZERO_STRUCTP(r->out.acct_handle);
1762 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1766 astate = talloc(dce_call->conn, struct lsa_account_state);
1767 if (astate == NULL) {
1768 return NT_STATUS_NO_MEMORY;
1771 astate->account_sid = dom_sid_dup(astate, r->in.sid);
1772 if (astate->account_sid == NULL) {
1773 talloc_free(astate);
1774 return NT_STATUS_NO_MEMORY;
1777 astate->policy = talloc_reference(astate, state);
1778 astate->access_mask = r->in.access_mask;
1780 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
1782 talloc_free(astate);
1783 return NT_STATUS_NO_MEMORY;
1786 ah->data = talloc_steal(ah, astate);
1788 *r->out.acct_handle = ah->wire_handle;
1790 return NT_STATUS_OK;
1795 lsa_EnumPrivsAccount
1797 static NTSTATUS lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
1798 TALLOC_CTX *mem_ctx,
1799 struct lsa_EnumPrivsAccount *r)
1801 struct dcesrv_handle *h;
1802 struct lsa_account_state *astate;
1804 struct ldb_message **res;
1805 const char * const attrs[] = { "privilege", NULL};
1806 struct ldb_message_element *el;
1809 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1813 r->out.privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
1814 r->out.privs->count = 0;
1815 r->out.privs->unknown = 0;
1816 r->out.privs->set = NULL;
1818 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
1819 if (sidstr == NULL) {
1820 return NT_STATUS_NO_MEMORY;
1823 ret = gendb_search(astate->policy->sam_ldb, mem_ctx, NULL, &res, attrs,
1824 "objectSid=%s", sidstr);
1826 return NT_STATUS_OK;
1829 el = ldb_msg_find_element(res[0], "privilege");
1830 if (el == NULL || el->num_values == 0) {
1831 return NT_STATUS_OK;
1834 r->out.privs->set = talloc_array(r->out.privs,
1835 struct lsa_LUIDAttribute, el->num_values);
1836 if (r->out.privs->set == NULL) {
1837 return NT_STATUS_NO_MEMORY;
1840 for (i=0;i<el->num_values;i++) {
1841 int id = sec_privilege_id((const char *)el->values[i].data);
1843 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1845 r->out.privs->set[i].attribute = 0;
1846 r->out.privs->set[i].luid.low = id;
1847 r->out.privs->set[i].luid.high = 0;
1850 r->out.privs->count = el->num_values;
1852 return NT_STATUS_OK;
1856 lsa_EnumAccountRights
1858 static NTSTATUS lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
1859 TALLOC_CTX *mem_ctx,
1860 struct lsa_EnumAccountRights *r)
1862 struct dcesrv_handle *h;
1863 struct lsa_policy_state *state;
1865 struct ldb_message **res;
1866 const char * const attrs[] = { "privilege", NULL};
1868 struct ldb_message_element *el;
1870 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1874 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
1875 if (sidstr == NULL) {
1876 return NT_STATUS_NO_MEMORY;
1879 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
1880 "(&(objectSid=%s)(privilege=*))", sidstr);
1882 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1885 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1888 DEBUG(3, ("searching for account rights for SID: %s failed: %s",
1889 dom_sid_string(mem_ctx, r->in.sid),
1890 ldb_errstring(state->sam_ldb)));
1891 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1894 el = ldb_msg_find_element(res[0], "privilege");
1895 if (el == NULL || el->num_values == 0) {
1896 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1899 r->out.rights->count = el->num_values;
1900 r->out.rights->names = talloc_array(r->out.rights,
1901 struct lsa_StringLarge, r->out.rights->count);
1902 if (r->out.rights->names == NULL) {
1903 return NT_STATUS_NO_MEMORY;
1906 for (i=0;i<el->num_values;i++) {
1907 r->out.rights->names[i].string = (const char *)el->values[i].data;
1910 return NT_STATUS_OK;
1916 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
1918 static NTSTATUS lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
1919 TALLOC_CTX *mem_ctx,
1920 struct lsa_policy_state *state,
1922 struct dom_sid *sid,
1923 const struct lsa_RightSet *rights)
1926 struct ldb_message *msg;
1927 struct ldb_message_element *el;
1929 struct lsa_EnumAccountRights r2;
1931 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, sid);
1932 if (sidstr == NULL) {
1933 return NT_STATUS_NO_MEMORY;
1936 msg = ldb_msg_new(mem_ctx);
1938 return NT_STATUS_NO_MEMORY;
1941 msg->dn = samdb_search_dn(state->sam_ldb, mem_ctx,
1942 NULL, "objectSid=%s", sidstr);
1943 if (msg->dn == NULL) {
1945 if (ldb_flag == LDB_FLAG_MOD_DELETE) {
1946 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1948 status = samdb_create_foreign_security_principal(state->sam_ldb, mem_ctx,
1950 if (!NT_STATUS_IS_OK(status)) {
1953 return NT_STATUS_NO_SUCH_USER;
1956 if (ldb_msg_add_empty(msg, "privilege", ldb_flag, NULL)) {
1957 return NT_STATUS_NO_MEMORY;
1960 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1963 r2.in.handle = &state->handle->wire_handle;
1965 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
1967 status = lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1968 if (!NT_STATUS_IS_OK(status)) {
1969 ZERO_STRUCTP(r2.out.rights);
1973 for (i=0;i<rights->count;i++) {
1974 if (sec_privilege_id(rights->names[i].string) == -1) {
1975 return NT_STATUS_NO_SUCH_PRIVILEGE;
1978 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1980 for (j=0;j<r2.out.rights->count;j++) {
1981 if (strcasecmp_m(r2.out.rights->names[j].string,
1982 rights->names[i].string) == 0) {
1986 if (j != r2.out.rights->count) continue;
1989 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
1990 if (ret != LDB_SUCCESS) {
1991 return NT_STATUS_NO_MEMORY;
1995 el = ldb_msg_find_element(msg, "privilege");
1997 return NT_STATUS_OK;
2000 ret = samdb_modify(state->sam_ldb, mem_ctx, msg);
2002 if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
2003 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2005 DEBUG(3, ("Could not %s attributes from %s: %s",
2006 ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add",
2007 ldb_dn_get_linearized(msg->dn), ldb_errstring(state->sam_ldb)));
2008 return NT_STATUS_UNEXPECTED_IO_ERROR;
2011 return NT_STATUS_OK;
2015 lsa_AddPrivilegesToAccount
2017 static NTSTATUS lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2018 struct lsa_AddPrivilegesToAccount *r)
2020 struct lsa_RightSet rights;
2021 struct dcesrv_handle *h;
2022 struct lsa_account_state *astate;
2025 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2029 rights.count = r->in.privs->count;
2030 rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
2031 if (rights.names == NULL) {
2032 return NT_STATUS_NO_MEMORY;
2034 for (i=0;i<rights.count;i++) {
2035 int id = r->in.privs->set[i].luid.low;
2036 if (r->in.privs->set[i].luid.high) {
2037 return NT_STATUS_NO_SUCH_PRIVILEGE;
2039 rights.names[i].string = sec_privilege_name(id);
2040 if (rights.names[i].string == NULL) {
2041 return NT_STATUS_NO_SUCH_PRIVILEGE;
2045 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2046 LDB_FLAG_MOD_ADD, astate->account_sid,
2052 lsa_RemovePrivilegesFromAccount
2054 static NTSTATUS lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2055 struct lsa_RemovePrivilegesFromAccount *r)
2057 struct lsa_RightSet *rights;
2058 struct dcesrv_handle *h;
2059 struct lsa_account_state *astate;
2062 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2066 rights = talloc(mem_ctx, struct lsa_RightSet);
2068 if (r->in.remove_all == 1 &&
2069 r->in.privs == NULL) {
2070 struct lsa_EnumAccountRights r2;
2073 r2.in.handle = &astate->policy->handle->wire_handle;
2074 r2.in.sid = astate->account_sid;
2075 r2.out.rights = rights;
2077 status = lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
2078 if (!NT_STATUS_IS_OK(status)) {
2082 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2083 LDB_FLAG_MOD_DELETE, astate->account_sid,
2087 if (r->in.remove_all != 0) {
2088 return NT_STATUS_INVALID_PARAMETER;
2091 rights->count = r->in.privs->count;
2092 rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
2093 if (rights->names == NULL) {
2094 return NT_STATUS_NO_MEMORY;
2096 for (i=0;i<rights->count;i++) {
2097 int id = r->in.privs->set[i].luid.low;
2098 if (r->in.privs->set[i].luid.high) {
2099 return NT_STATUS_NO_SUCH_PRIVILEGE;
2101 rights->names[i].string = sec_privilege_name(id);
2102 if (rights->names[i].string == NULL) {
2103 return NT_STATUS_NO_SUCH_PRIVILEGE;
2107 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2108 LDB_FLAG_MOD_DELETE, astate->account_sid,
2114 lsa_GetQuotasForAccount
2116 static NTSTATUS lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2117 struct lsa_GetQuotasForAccount *r)
2119 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2124 lsa_SetQuotasForAccount
2126 static NTSTATUS lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2127 struct lsa_SetQuotasForAccount *r)
2129 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2134 lsa_GetSystemAccessAccount
2136 static NTSTATUS lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2137 struct lsa_GetSystemAccessAccount *r)
2139 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2144 lsa_SetSystemAccessAccount
2146 static NTSTATUS lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2147 struct lsa_SetSystemAccessAccount *r)
2149 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2156 static NTSTATUS lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2157 struct lsa_CreateSecret *r)
2159 struct dcesrv_handle *policy_handle;
2160 struct lsa_policy_state *policy_state;
2161 struct lsa_secret_state *secret_state;
2162 struct dcesrv_handle *handle;
2163 struct ldb_message **msgs, *msg;
2165 const char *attrs[] = {
2173 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2174 ZERO_STRUCTP(r->out.sec_handle);
2176 policy_state = policy_handle->data;
2178 if (!r->in.name.string) {
2179 return NT_STATUS_INVALID_PARAMETER;
2182 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2183 if (!secret_state) {
2184 return NT_STATUS_NO_MEMORY;
2186 secret_state->policy = policy_state;
2188 msg = ldb_msg_new(mem_ctx);
2190 return NT_STATUS_NO_MEMORY;
2193 if (strncmp("G$", r->in.name.string, 2) == 0) {
2195 name = &r->in.name.string[2];
2196 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
2197 secret_state->global = True;
2199 if (strlen(name) < 1) {
2200 return NT_STATUS_INVALID_PARAMETER;
2203 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
2204 /* search for the secret record */
2205 ret = gendb_search(secret_state->sam_ldb,
2206 mem_ctx, policy_state->system_dn, &msgs, attrs,
2207 "(&(cn=%s)(objectclass=secret))",
2210 return NT_STATUS_OBJECT_NAME_COLLISION;
2214 DEBUG(0,("Failure searching for CN=%s: %s\n",
2215 name2, ldb_errstring(secret_state->sam_ldb)));
2216 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2219 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
2220 if (!name2 || ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
2221 return NT_STATUS_NO_MEMORY;
2224 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
2227 secret_state->global = False;
2229 name = r->in.name.string;
2230 if (strlen(name) < 1) {
2231 return NT_STATUS_INVALID_PARAMETER;
2234 secret_state->sam_ldb = talloc_reference(secret_state, secrets_db_connect(mem_ctx));
2235 /* search for the secret record */
2236 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2237 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2239 "(&(cn=%s)(objectclass=secret))",
2240 ldb_binary_encode_string(mem_ctx, name));
2242 return NT_STATUS_OBJECT_NAME_COLLISION;
2246 DEBUG(0,("Failure searching for CN=%s: %s\n",
2247 name, ldb_errstring(secret_state->sam_ldb)));
2248 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2251 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name);
2252 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
2255 /* pull in all the template attributes. Note this is always from the global samdb */
2256 ret = samdb_copy_template(secret_state->policy->sam_ldb, msg,
2257 "(&(cn=TemplateSecret)(objectclass=secretTemplate))", &errstr);
2259 DEBUG(0,("Failed to load TemplateSecret from samdb: %s\n",
2261 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2264 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
2266 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
2268 /* create the secret */
2269 ret = samdb_add(secret_state->sam_ldb, mem_ctx, msg);
2271 DEBUG(0,("Failed to create secret record %s: %s\n",
2272 ldb_dn_get_linearized(msg->dn),
2273 ldb_errstring(secret_state->sam_ldb)));
2274 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2277 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2279 return NT_STATUS_NO_MEMORY;
2282 handle->data = talloc_steal(handle, secret_state);
2284 secret_state->access_mask = r->in.access_mask;
2285 secret_state->policy = talloc_reference(secret_state, policy_state);
2287 *r->out.sec_handle = handle->wire_handle;
2289 return NT_STATUS_OK;
2296 static NTSTATUS lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2297 struct lsa_OpenSecret *r)
2299 struct dcesrv_handle *policy_handle;
2301 struct lsa_policy_state *policy_state;
2302 struct lsa_secret_state *secret_state;
2303 struct dcesrv_handle *handle;
2304 struct ldb_message **msgs;
2305 const char *attrs[] = {
2313 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2314 ZERO_STRUCTP(r->out.sec_handle);
2315 policy_state = policy_handle->data;
2317 if (!r->in.name.string) {
2318 return NT_STATUS_INVALID_PARAMETER;
2321 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2322 if (!secret_state) {
2323 return NT_STATUS_NO_MEMORY;
2325 secret_state->policy = policy_state;
2327 if (strncmp("G$", r->in.name.string, 2) == 0) {
2328 name = &r->in.name.string[2];
2329 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
2330 secret_state->global = True;
2332 if (strlen(name) < 1) {
2333 return NT_STATUS_INVALID_PARAMETER;
2336 /* search for the secret record */
2337 ret = gendb_search(secret_state->sam_ldb,
2338 mem_ctx, policy_state->system_dn, &msgs, attrs,
2339 "(&(cn=%s Secret)(objectclass=secret))",
2340 ldb_binary_encode_string(mem_ctx, name));
2342 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2346 DEBUG(0,("Found %d records matching DN %s\n", ret,
2347 ldb_dn_get_linearized(policy_state->system_dn)));
2348 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2352 secret_state->sam_ldb = talloc_reference(secret_state, secrets_db_connect(mem_ctx));
2354 secret_state->global = False;
2355 name = r->in.name.string;
2356 if (strlen(name) < 1) {
2357 return NT_STATUS_INVALID_PARAMETER;
2360 /* search for the secret record */
2361 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2362 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2364 "(&(cn=%s)(objectclass=secret))",
2365 ldb_binary_encode_string(mem_ctx, name));
2367 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2371 DEBUG(0,("Found %d records matching DN %s\n", ret,
2372 ldb_dn_get_linearized(policy_state->system_dn)));
2373 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2377 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
2379 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2381 return NT_STATUS_NO_MEMORY;
2384 handle->data = talloc_steal(handle, secret_state);
2386 secret_state->access_mask = r->in.access_mask;
2387 secret_state->policy = talloc_reference(secret_state, policy_state);
2389 *r->out.sec_handle = handle->wire_handle;
2391 return NT_STATUS_OK;
2398 static NTSTATUS lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2399 struct lsa_SetSecret *r)
2402 struct dcesrv_handle *h;
2403 struct lsa_secret_state *secret_state;
2404 struct ldb_message *msg;
2405 DATA_BLOB session_key;
2406 DATA_BLOB crypt_secret, secret;
2409 NTSTATUS status = NT_STATUS_OK;
2411 struct timeval now = timeval_current();
2412 NTTIME nt_now = timeval_to_nttime(&now);
2414 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2416 secret_state = h->data;
2418 msg = ldb_msg_new(mem_ctx);
2420 return NT_STATUS_NO_MEMORY;
2423 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
2425 return NT_STATUS_NO_MEMORY;
2427 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2428 if (!NT_STATUS_IS_OK(status)) {
2432 if (r->in.old_val) {
2434 crypt_secret.data = r->in.old_val->data;
2435 crypt_secret.length = r->in.old_val->size;
2437 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2438 if (!NT_STATUS_IS_OK(status)) {
2442 val.data = secret.data;
2443 val.length = secret.length;
2446 if (samdb_msg_add_value(secret_state->sam_ldb,
2447 mem_ctx, msg, "priorValue", &val) != 0) {
2448 return NT_STATUS_NO_MEMORY;
2451 /* set old value mtime */
2452 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2453 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
2454 return NT_STATUS_NO_MEMORY;
2457 if (!r->in.new_val) {
2458 /* This behaviour varies depending of if this is a local, or a global secret... */
2459 if (secret_state->global) {
2460 /* set old value mtime */
2461 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2462 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2463 return NT_STATUS_NO_MEMORY;
2466 if (samdb_msg_add_delete(secret_state->sam_ldb,
2467 mem_ctx, msg, "currentValue")) {
2468 return NT_STATUS_NO_MEMORY;
2470 if (samdb_msg_add_delete(secret_state->sam_ldb,
2471 mem_ctx, msg, "lastSetTime")) {
2472 return NT_STATUS_NO_MEMORY;
2478 if (r->in.new_val) {
2480 crypt_secret.data = r->in.new_val->data;
2481 crypt_secret.length = r->in.new_val->size;
2483 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2484 if (!NT_STATUS_IS_OK(status)) {
2488 val.data = secret.data;
2489 val.length = secret.length;
2492 if (samdb_msg_add_value(secret_state->sam_ldb,
2493 mem_ctx, msg, "currentValue", &val) != 0) {
2494 return NT_STATUS_NO_MEMORY;
2497 /* set new value mtime */
2498 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2499 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2500 return NT_STATUS_NO_MEMORY;
2503 /* If the old value is not set, then migrate the
2504 * current value to the old value */
2505 if (!r->in.old_val) {
2506 const struct ldb_val *new_val;
2507 NTTIME last_set_time;
2508 struct ldb_message **res;
2509 const char *attrs[] = {
2515 /* search for the secret record */
2516 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
2517 secret_state->secret_dn, &res, attrs);
2519 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2523 DEBUG(0,("Found %d records matching dn=%s\n", ret,
2524 ldb_dn_get_linearized(secret_state->secret_dn)));
2525 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2528 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2529 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2533 if (samdb_msg_add_value(secret_state->sam_ldb,
2534 mem_ctx, msg, "priorValue",
2536 return NT_STATUS_NO_MEMORY;
2540 /* set new value mtime */
2541 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2542 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2543 mem_ctx, msg, "priorSetTime", last_set_time) != 0) {
2544 return NT_STATUS_NO_MEMORY;
2550 /* modify the samdb record */
2551 ret = samdb_replace(secret_state->sam_ldb, mem_ctx, msg);
2553 /* we really need samdb.c to return NTSTATUS */
2554 return NT_STATUS_UNSUCCESSFUL;
2557 return NT_STATUS_OK;
2564 static NTSTATUS lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2565 struct lsa_QuerySecret *r)
2567 struct dcesrv_handle *h;
2568 struct lsa_secret_state *secret_state;
2569 struct ldb_message *msg;
2570 DATA_BLOB session_key;
2571 DATA_BLOB crypt_secret, secret;
2573 struct ldb_message **res;
2574 const char *attrs[] = {
2584 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2586 secret_state = h->data;
2588 /* pull all the user attributes */
2589 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2590 secret_state->secret_dn, &res, attrs);
2592 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2596 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2597 if (!NT_STATUS_IS_OK(nt_status)) {
2601 if (r->in.old_val) {
2602 const struct ldb_val *prior_val;
2603 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2604 if (!r->out.old_val) {
2605 return NT_STATUS_NO_MEMORY;
2607 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
2609 if (prior_val && prior_val->length) {
2610 secret.data = prior_val->data;
2611 secret.length = prior_val->length;
2614 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2615 if (!crypt_secret.length) {
2616 return NT_STATUS_NO_MEMORY;
2618 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2619 if (!r->out.old_val->buf) {
2620 return NT_STATUS_NO_MEMORY;
2622 r->out.old_val->buf->size = crypt_secret.length;
2623 r->out.old_val->buf->length = crypt_secret.length;
2624 r->out.old_val->buf->data = crypt_secret.data;
2628 if (r->in.old_mtime) {
2629 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2630 if (!r->out.old_mtime) {
2631 return NT_STATUS_NO_MEMORY;
2633 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
2636 if (r->in.new_val) {
2637 const struct ldb_val *new_val;
2638 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2639 if (!r->out.new_val) {
2640 return NT_STATUS_NO_MEMORY;
2643 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2645 if (new_val && new_val->length) {
2646 secret.data = new_val->data;
2647 secret.length = new_val->length;
2650 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2651 if (!crypt_secret.length) {
2652 return NT_STATUS_NO_MEMORY;
2654 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2655 if (!r->out.new_val->buf) {
2656 return NT_STATUS_NO_MEMORY;
2658 r->out.new_val->buf->length = crypt_secret.length;
2659 r->out.new_val->buf->size = crypt_secret.length;
2660 r->out.new_val->buf->data = crypt_secret.data;
2664 if (r->in.new_mtime) {
2665 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2666 if (!r->out.new_mtime) {
2667 return NT_STATUS_NO_MEMORY;
2669 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2672 return NT_STATUS_OK;
2679 static NTSTATUS lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
2680 TALLOC_CTX *mem_ctx,
2681 struct lsa_LookupPrivValue *r)
2683 struct dcesrv_handle *h;
2684 struct lsa_policy_state *state;
2687 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2691 id = sec_privilege_id(r->in.name->string);
2693 return NT_STATUS_NO_SUCH_PRIVILEGE;
2696 r->out.luid->low = id;
2697 r->out.luid->high = 0;
2699 return NT_STATUS_OK;
2706 static NTSTATUS lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
2707 TALLOC_CTX *mem_ctx,
2708 struct lsa_LookupPrivName *r)
2710 struct dcesrv_handle *h;
2711 struct lsa_policy_state *state;
2712 const char *privname;
2714 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2718 if (r->in.luid->high != 0) {
2719 return NT_STATUS_NO_SUCH_PRIVILEGE;
2722 privname = sec_privilege_name(r->in.luid->low);
2723 if (privname == NULL) {
2724 return NT_STATUS_NO_SUCH_PRIVILEGE;
2727 r->out.name = talloc(mem_ctx, struct lsa_StringLarge);
2728 if (r->out.name == NULL) {
2729 return NT_STATUS_NO_MEMORY;
2731 r->out.name->string = privname;
2733 return NT_STATUS_OK;
2738 lsa_LookupPrivDisplayName
2740 static NTSTATUS lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
2741 TALLOC_CTX *mem_ctx,
2742 struct lsa_LookupPrivDisplayName *r)
2744 struct dcesrv_handle *h;
2745 struct lsa_policy_state *state;
2748 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2752 id = sec_privilege_id(r->in.name->string);
2754 return NT_STATUS_NO_SUCH_PRIVILEGE;
2757 r->out.disp_name = talloc(mem_ctx, struct lsa_StringLarge);
2758 if (r->out.disp_name == NULL) {
2759 return NT_STATUS_NO_MEMORY;
2762 r->out.disp_name->string = sec_privilege_display_name(id, r->in.language_id);
2763 if (r->out.disp_name->string == NULL) {
2764 return NT_STATUS_INTERNAL_ERROR;
2767 return NT_STATUS_OK;
2774 static NTSTATUS lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2775 struct lsa_DeleteObject *r)
2777 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2782 lsa_EnumAccountsWithUserRight
2784 static NTSTATUS lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
2785 TALLOC_CTX *mem_ctx,
2786 struct lsa_EnumAccountsWithUserRight *r)
2788 struct dcesrv_handle *h;
2789 struct lsa_policy_state *state;
2791 struct ldb_message **res;
2792 const char * const attrs[] = { "objectSid", NULL};
2793 const char *privname;
2795 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2799 if (r->in.name == NULL) {
2800 return NT_STATUS_NO_SUCH_PRIVILEGE;
2803 privname = r->in.name->string;
2804 if (sec_privilege_id(privname) == -1) {
2805 return NT_STATUS_NO_SUCH_PRIVILEGE;
2808 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
2809 "privilege=%s", privname);
2811 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2814 return NT_STATUS_NO_MORE_ENTRIES;
2817 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2818 if (r->out.sids->sids == NULL) {
2819 return NT_STATUS_NO_MEMORY;
2821 for (i=0;i<ret;i++) {
2822 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2823 res[i], "objectSid");
2824 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2826 r->out.sids->num_sids = ret;
2828 return NT_STATUS_OK;
2833 lsa_AddAccountRights
2835 static NTSTATUS lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
2836 TALLOC_CTX *mem_ctx,
2837 struct lsa_AddAccountRights *r)
2839 struct dcesrv_handle *h;
2840 struct lsa_policy_state *state;
2842 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2846 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2848 r->in.sid, r->in.rights);
2853 lsa_RemoveAccountRights
2855 static NTSTATUS lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
2856 TALLOC_CTX *mem_ctx,
2857 struct lsa_RemoveAccountRights *r)
2859 struct dcesrv_handle *h;
2860 struct lsa_policy_state *state;
2862 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2866 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2867 LDB_FLAG_MOD_DELETE,
2868 r->in.sid, r->in.rights);
2873 lsa_StorePrivateData
2875 static NTSTATUS lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2876 struct lsa_StorePrivateData *r)
2878 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2883 lsa_RetrievePrivateData
2885 static NTSTATUS lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2886 struct lsa_RetrievePrivateData *r)
2888 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2895 static NTSTATUS lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2896 struct lsa_GetUserName *r)
2898 NTSTATUS status = NT_STATUS_OK;
2899 const char *account_name;
2900 const char *authority_name;
2901 struct lsa_String *_account_name;
2902 struct lsa_StringPointer *_authority_name = NULL;
2904 /* this is what w2k3 does */
2905 r->out.account_name = r->in.account_name;
2906 r->out.authority_name = r->in.authority_name;
2908 if (r->in.account_name && r->in.account_name->string) {
2909 return NT_STATUS_INVALID_PARAMETER;
2912 if (r->in.authority_name &&
2913 r->in.authority_name->string &&
2914 r->in.authority_name->string->string) {
2915 return NT_STATUS_INVALID_PARAMETER;
2918 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
2919 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
2921 _account_name = talloc(mem_ctx, struct lsa_String);
2922 NT_STATUS_HAVE_NO_MEMORY(_account_name);
2923 _account_name->string = account_name;
2925 if (r->in.authority_name) {
2926 _authority_name = talloc(mem_ctx, struct lsa_StringPointer);
2927 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
2928 _authority_name->string = talloc(mem_ctx, struct lsa_String);
2929 NT_STATUS_HAVE_NO_MEMORY(_authority_name->string);
2930 _authority_name->string->string = authority_name;
2933 r->out.account_name = _account_name;
2934 r->out.authority_name = _authority_name;
2942 static NTSTATUS lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
2943 TALLOC_CTX *mem_ctx,
2944 struct lsa_SetInfoPolicy2 *r)
2946 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2950 lsa_QueryDomainInformationPolicy
2952 static NTSTATUS lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2953 TALLOC_CTX *mem_ctx,
2954 struct lsa_QueryDomainInformationPolicy *r)
2956 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2960 lsa_SetDomInfoPolicy
2962 static NTSTATUS lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2963 TALLOC_CTX *mem_ctx,
2964 struct lsa_SetDomainInformationPolicy *r)
2966 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2972 static NTSTATUS lsa_TestCall(struct dcesrv_call_state *dce_call,
2973 TALLOC_CTX *mem_ctx,
2974 struct lsa_TestCall *r)
2976 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2980 lookup a SID for 1 name
2982 static NTSTATUS lsa_lookup_name(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
2983 const char *name, struct dom_sid **sid, uint32_t *atype)
2986 struct ldb_message **res;
2987 const char * const attrs[] = { "objectSid", "sAMAccountType", NULL};
2990 p = strchr_m(name, '\\');
2992 /* TODO: properly parse the domain prefix here, and use it to
2997 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs, "sAMAccountName=%s", ldb_binary_encode_string(mem_ctx, name));
2999 *sid = samdb_result_dom_sid(mem_ctx, res[0], "objectSid");
3001 return NT_STATUS_INVALID_SID;
3004 *atype = samdb_result_uint(res[0], "sAMAccountType", 0);
3006 return NT_STATUS_OK;
3009 /* need to add a call into sidmap to check for a allocated sid */
3011 return NT_STATUS_INVALID_SID;
3018 static NTSTATUS lsa_LookupNames3(struct dcesrv_call_state *dce_call,
3019 TALLOC_CTX *mem_ctx,
3020 struct lsa_LookupNames3 *r)
3022 struct lsa_policy_state *policy_state;
3023 struct dcesrv_handle *policy_handle;
3025 NTSTATUS status = NT_STATUS_OK;
3027 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
3029 policy_state = policy_handle->data;
3031 r->out.domains = NULL;
3033 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
3034 if (r->out.domains == NULL) {
3035 return NT_STATUS_NO_MEMORY;
3038 r->out.sids = talloc_zero(mem_ctx, struct lsa_TransSidArray3);
3039 if (r->out.sids == NULL) {
3040 return NT_STATUS_NO_MEMORY;
3045 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid3,
3047 if (r->out.sids->sids == NULL) {
3048 return NT_STATUS_NO_MEMORY;
3051 for (i=0;i<r->in.num_names;i++) {
3052 const char *name = r->in.names[i].string;
3053 struct dom_sid *sid;
3054 uint32_t atype, rtype, sid_index;
3057 r->out.sids->count++;
3060 r->out.sids->sids[i].sid_type = SID_NAME_UNKNOWN;
3061 r->out.sids->sids[i].sid = NULL;
3062 r->out.sids->sids[i].sid_index = 0xFFFFFFFF;
3063 r->out.sids->sids[i].unknown = 0;
3065 status2 = lsa_lookup_name(policy_state, mem_ctx, name, &sid, &atype);
3066 if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
3067 status = STATUS_SOME_UNMAPPED;
3071 rtype = samdb_atype_map(atype);
3072 if (rtype == SID_NAME_UNKNOWN) {
3073 status = STATUS_SOME_UNMAPPED;
3077 status2 = lsa_authority_list(policy_state, mem_ctx, sid, r->out.domains, &sid_index);
3078 if (!NT_STATUS_IS_OK(status2)) {
3082 r->out.sids->sids[i].sid_type = rtype;
3083 r->out.sids->sids[i].sid = sid;
3084 r->out.sids->sids[i].sid_index = sid_index;
3085 r->out.sids->sids[i].unknown = 0;
3094 Identical to LookupNames3, but doesn't take a policy handle
3097 static NTSTATUS lsa_LookupNames4(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3098 struct lsa_LookupNames4 *r)
3100 struct lsa_LookupNames3 r2;
3101 struct lsa_OpenPolicy2 pol;
3103 struct dcesrv_handle *h;
3105 /* No policy handle on the wire, so make one up here */
3106 r2.in.handle = talloc(mem_ctx, struct policy_handle);
3107 if (!r2.in.handle) {
3108 return NT_STATUS_NO_MEMORY;
3111 pol.out.handle = r2.in.handle;
3112 pol.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3114 pol.in.system_name = NULL;
3115 status = lsa_OpenPolicy2(dce_call, mem_ctx, &pol);
3116 if (!NT_STATUS_IS_OK(status)) {
3120 /* ensure this handle goes away at the end of this call */
3121 DCESRV_PULL_HANDLE(h, r2.in.handle, LSA_HANDLE_POLICY);
3122 talloc_steal(mem_ctx, h);
3124 r2.in.num_names = r->in.num_names;
3125 r2.in.names = r->in.names;
3126 r2.in.sids = r->in.sids;
3127 r2.in.count = r->in.count;
3128 r2.in.unknown1 = r->in.unknown1;
3129 r2.in.unknown2 = r->in.unknown2;
3130 r2.out.domains = r->out.domains;
3131 r2.out.sids = r->out.sids;
3132 r2.out.count = r->out.count;
3134 status = lsa_LookupNames3(dce_call, mem_ctx, &r2);
3135 if (dce_call->fault_code != 0) {
3139 r->out.domains = r2.out.domains;
3140 r->out.sids = r2.out.sids;
3141 r->out.count = r2.out.count;
3148 static NTSTATUS lsa_LookupNames2(struct dcesrv_call_state *dce_call,
3149 TALLOC_CTX *mem_ctx,
3150 struct lsa_LookupNames2 *r)
3152 struct lsa_policy_state *state;
3153 struct dcesrv_handle *h;
3155 NTSTATUS status = NT_STATUS_OK;
3157 r->out.domains = NULL;
3159 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3163 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
3164 if (r->out.domains == NULL) {
3165 return NT_STATUS_NO_MEMORY;
3168 r->out.sids = talloc_zero(mem_ctx, struct lsa_TransSidArray2);
3169 if (r->out.sids == NULL) {
3170 return NT_STATUS_NO_MEMORY;
3175 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid2,
3177 if (r->out.sids->sids == NULL) {
3178 return NT_STATUS_NO_MEMORY;
3181 for (i=0;i<r->in.num_names;i++) {
3182 const char *name = r->in.names[i].string;
3183 struct dom_sid *sid;
3184 uint32_t atype, rtype, sid_index;
3187 r->out.sids->count++;
3190 r->out.sids->sids[i].sid_type = SID_NAME_UNKNOWN;
3191 r->out.sids->sids[i].rid = 0xFFFFFFFF;
3192 r->out.sids->sids[i].sid_index = 0xFFFFFFFF;
3193 r->out.sids->sids[i].unknown = 0;
3195 status2 = lsa_lookup_name(state, mem_ctx, name, &sid, &atype);
3196 if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
3197 status = STATUS_SOME_UNMAPPED;
3201 rtype = samdb_atype_map(atype);
3202 if (rtype == SID_NAME_UNKNOWN) {
3203 status = STATUS_SOME_UNMAPPED;
3207 status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
3208 if (!NT_STATUS_IS_OK(status2)) {
3212 r->out.sids->sids[i].sid_type = rtype;
3213 r->out.sids->sids[i].rid = sid->sub_auths[sid->num_auths-1];
3214 r->out.sids->sids[i].sid_index = sid_index;
3215 r->out.sids->sids[i].unknown = 0;
3224 static NTSTATUS lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3225 struct lsa_LookupNames *r)
3227 struct lsa_LookupNames2 r2;
3231 r2.in.handle = r->in.handle;
3232 r2.in.num_names = r->in.num_names;
3233 r2.in.names = r->in.names;
3235 r2.in.level = r->in.level;
3236 r2.in.count = r->in.count;
3239 r2.out.count = r->out.count;
3241 status = lsa_LookupNames2(dce_call, mem_ctx, &r2);
3242 if (dce_call->fault_code != 0) {
3246 r->out.domains = r2.out.domains;
3247 r->out.sids = talloc(mem_ctx, struct lsa_TransSidArray);
3248 if (r->out.sids == NULL) {
3249 return NT_STATUS_NO_MEMORY;
3251 r->out.sids->count = r2.out.sids->count;
3252 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid,
3253 r->out.sids->count);
3254 if (r->out.sids->sids == NULL) {
3255 return NT_STATUS_NO_MEMORY;
3257 for (i=0;i<r->out.sids->count;i++) {
3258 r->out.sids->sids[i].sid_type = r2.out.sids->sids[i].sid_type;
3259 r->out.sids->sids[i].rid = r2.out.sids->sids[i].rid;
3260 r->out.sids->sids[i].sid_index = r2.out.sids->sids[i].sid_index;
3269 static NTSTATUS lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3270 struct lsa_CREDRWRITE *r)
3272 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3279 static NTSTATUS lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3280 struct lsa_CREDRREAD *r)
3282 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3289 static NTSTATUS lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3290 struct lsa_CREDRENUMERATE *r)
3292 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3297 lsa_CREDRWRITEDOMAINCREDENTIALS
3299 static NTSTATUS lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3300 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3302 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3307 lsa_CREDRREADDOMAINCREDENTIALS
3309 static NTSTATUS lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3310 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3312 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3319 static NTSTATUS lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3320 struct lsa_CREDRDELETE *r)
3322 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3327 lsa_CREDRGETTARGETINFO
3329 static NTSTATUS lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3330 struct lsa_CREDRGETTARGETINFO *r)
3332 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3337 lsa_CREDRPROFILELOADED
3339 static NTSTATUS lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3340 struct lsa_CREDRPROFILELOADED *r)
3342 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3347 lsa_CREDRGETSESSIONTYPES
3349 static NTSTATUS lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3350 struct lsa_CREDRGETSESSIONTYPES *r)
3352 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3357 lsa_LSARREGISTERAUDITEVENT
3359 static NTSTATUS lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3360 struct lsa_LSARREGISTERAUDITEVENT *r)
3362 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3367 lsa_LSARGENAUDITEVENT
3369 static NTSTATUS lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3370 struct lsa_LSARGENAUDITEVENT *r)
3372 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3377 lsa_LSARUNREGISTERAUDITEVENT
3379 static NTSTATUS lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3380 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3382 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3387 lsa_LSARQUERYFORESTTRUSTINFORMATION
3389 static NTSTATUS lsa_LSARQUERYFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3390 struct lsa_LSARQUERYFORESTTRUSTINFORMATION *r)
3392 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3397 lsa_LSARSETFORESTTRUSTINFORMATION
3399 static NTSTATUS lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3400 struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
3402 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3409 static NTSTATUS lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3410 struct lsa_CREDRRENAME *r)
3412 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3418 lsa_LSAROPENPOLICYSCE
3420 static NTSTATUS lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3421 struct lsa_LSAROPENPOLICYSCE *r)
3423 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3428 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
3430 static NTSTATUS lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3431 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
3433 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3438 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
3440 static NTSTATUS lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3441 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
3443 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3448 lsa_LSARADTREPORTSECURITYEVENT
3450 static NTSTATUS lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3451 struct lsa_LSARADTREPORTSECURITYEVENT *r)
3453 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3457 /* include the generated boilerplate */
3458 #include "librpc/gen_ndr/ndr_lsa_s.c"
3462 /*****************************************
3463 NOTE! The remaining calls below were
3464 removed in w2k3, so the DCESRV_FAULT()
3465 replies are the correct implementation. Do
3466 not try and fill these in with anything else
3467 ******************************************/
3470 dssetup_DsRoleDnsNameToFlatName
3472 static WERROR dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3473 struct dssetup_DsRoleDnsNameToFlatName *r)
3475 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3480 dssetup_DsRoleDcAsDc
3482 static WERROR dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3483 struct dssetup_DsRoleDcAsDc *r)
3485 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3490 dssetup_DsRoleDcAsReplica
3492 static WERROR dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3493 struct dssetup_DsRoleDcAsReplica *r)
3495 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3500 dssetup_DsRoleDemoteDc
3502 static WERROR dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3503 struct dssetup_DsRoleDemoteDc *r)
3505 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3510 dssetup_DsRoleGetDcOperationProgress
3512 static WERROR dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3513 struct dssetup_DsRoleGetDcOperationProgress *r)
3515 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3520 dssetup_DsRoleGetDcOperationResults
3522 static WERROR dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3523 struct dssetup_DsRoleGetDcOperationResults *r)
3525 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3530 dssetup_DsRoleCancel
3532 static WERROR dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3533 struct dssetup_DsRoleCancel *r)
3535 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3540 dssetup_DsRoleServerSaveStateForUpgrade
3542 static WERROR dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3543 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
3545 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3550 dssetup_DsRoleUpgradeDownlevelServer
3552 static WERROR dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3553 struct dssetup_DsRoleUpgradeDownlevelServer *r)
3555 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3560 dssetup_DsRoleAbortDownlevelServerUpgrade
3562 static WERROR dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3563 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
3565 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3569 /* include the generated boilerplate */
3570 #include "librpc/gen_ndr/ndr_dssetup_s.c"
3572 NTSTATUS dcerpc_server_lsa_init(void)
3576 ret = dcerpc_server_dssetup_init();
3577 if (!NT_STATUS_IS_OK(ret)) {
3580 ret = dcerpc_server_lsarpc_init();
3581 if (!NT_STATUS_IS_OK(ret)) {