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 3 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, see <http://www.gnu.org/licenses/>.
24 #include "rpc_server/dcerpc_server.h"
25 #include "rpc_server/common/common.h"
26 #include "auth/auth.h"
27 #include "dsdb/samdb/samdb.h"
28 #include "libcli/ldap/ldap.h"
29 #include "lib/ldb/include/ldb_errors.h"
30 #include "libcli/security/security.h"
31 #include "libcli/auth/libcli_auth.h"
32 #include "param/secrets.h"
34 #include "librpc/gen_ndr/ndr_dssetup.h"
37 this type allows us to distinguish handle types
43 LSA_HANDLE_TRUSTED_DOMAIN
47 state associated with a lsa_OpenPolicy() operation
49 struct lsa_policy_state {
50 struct dcesrv_handle *handle;
51 struct ldb_context *sam_ldb;
52 struct sidmap_context *sidmap;
54 struct ldb_dn *domain_dn;
55 struct ldb_dn *forest_dn;
56 struct ldb_dn *builtin_dn;
57 struct ldb_dn *system_dn;
58 const char *domain_name;
59 const char *domain_dns;
60 const char *forest_dns;
61 struct dom_sid *domain_sid;
62 struct GUID domain_guid;
63 struct dom_sid *builtin_sid;
69 state associated with a lsa_OpenAccount() operation
71 struct lsa_account_state {
72 struct lsa_policy_state *policy;
74 struct dom_sid *account_sid;
79 state associated with a lsa_OpenSecret() operation
81 struct lsa_secret_state {
82 struct lsa_policy_state *policy;
84 struct ldb_dn *secret_dn;
85 struct ldb_context *sam_ldb;
90 state associated with a lsa_OpenTrustedDomain() operation
92 struct lsa_trusted_domain_state {
93 struct lsa_policy_state *policy;
95 struct ldb_dn *trusted_domain_dn;
98 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
100 struct lsa_EnumAccountRights *r);
102 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
104 struct lsa_policy_state *state,
107 const struct lsa_RightSet *rights);
112 static NTSTATUS dcesrv_lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
115 struct dcesrv_handle *h;
117 *r->out.handle = *r->in.handle;
119 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
123 ZERO_STRUCTP(r->out.handle);
132 static NTSTATUS dcesrv_lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
133 struct lsa_Delete *r)
135 struct dcesrv_handle *h;
138 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
139 if (h->wire_handle.handle_type == LSA_HANDLE_SECRET) {
140 struct lsa_secret_state *secret_state = h->data;
141 ret = samdb_delete(secret_state->sam_ldb, mem_ctx, secret_state->secret_dn);
144 return NT_STATUS_INVALID_HANDLE;
148 } else if (h->wire_handle.handle_type == LSA_HANDLE_TRUSTED_DOMAIN) {
149 struct lsa_trusted_domain_state *trusted_domain_state = h->data;
150 ret = samdb_delete(trusted_domain_state->policy->sam_ldb, mem_ctx,
151 trusted_domain_state->trusted_domain_dn);
154 return NT_STATUS_INVALID_HANDLE;
158 } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
159 struct lsa_RightSet *rights;
160 struct lsa_account_state *astate;
161 struct lsa_EnumAccountRights r2;
164 rights = talloc(mem_ctx, struct lsa_RightSet);
166 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
170 r2.in.handle = &astate->policy->handle->wire_handle;
171 r2.in.sid = astate->account_sid;
172 r2.out.rights = rights;
174 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
175 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
179 if (!NT_STATUS_IS_OK(status)) {
183 status = dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
184 LDB_FLAG_MOD_DELETE, astate->account_sid,
186 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
190 if (!NT_STATUS_IS_OK(status)) {
195 return NT_STATUS_INVALID_HANDLE;
202 static NTSTATUS dcesrv_lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
203 struct lsa_EnumPrivs *r)
205 struct dcesrv_handle *h;
206 struct lsa_policy_state *state;
208 const char *privname;
210 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
214 i = *r->in.resume_handle;
217 while ((privname = sec_privilege_name(i)) &&
218 r->out.privs->count < r->in.max_count) {
219 struct lsa_PrivEntry *e;
221 r->out.privs->privs = talloc_realloc(r->out.privs,
223 struct lsa_PrivEntry,
224 r->out.privs->count+1);
225 if (r->out.privs->privs == NULL) {
226 return NT_STATUS_NO_MEMORY;
228 e = &r->out.privs->privs[r->out.privs->count];
231 e->name.string = privname;
232 r->out.privs->count++;
236 *r->out.resume_handle = i;
245 static NTSTATUS dcesrv_lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
246 struct lsa_QuerySecurity *r)
248 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
255 static NTSTATUS dcesrv_lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
256 struct lsa_SetSecObj *r)
258 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
265 static NTSTATUS dcesrv_lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
266 struct lsa_ChangePassword *r)
268 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
271 static NTSTATUS dcesrv_lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
272 struct lsa_policy_state **_state)
274 struct lsa_policy_state *state;
275 struct ldb_dn *partitions_basedn;
276 struct ldb_result *dom_res;
277 const char *dom_attrs[] = {
284 struct ldb_result *ref_res;
285 struct ldb_result *forest_ref_res;
286 const char *ref_attrs[] = {
293 state = talloc(mem_ctx, struct lsa_policy_state);
295 return NT_STATUS_NO_MEMORY;
298 /* make sure the sam database is accessible */
299 state->sam_ldb = samdb_connect(state, dce_call->conn->auth_state.session_info);
300 if (state->sam_ldb == NULL) {
301 return NT_STATUS_INVALID_SYSTEM_SERVICE;
304 partitions_basedn = samdb_partitions_dn(state->sam_ldb, mem_ctx);
306 state->sidmap = sidmap_open(state);
307 if (state->sidmap == NULL) {
308 return NT_STATUS_INVALID_SYSTEM_SERVICE;
311 /* work out the domain_dn - useful for so many calls its worth
313 state->domain_dn = samdb_base_dn(state->sam_ldb);
314 if (!state->domain_dn) {
315 return NT_STATUS_NO_MEMORY;
318 /* work out the forest root_dn - useful for so many calls its worth
320 state->forest_dn = samdb_root_dn(state->sam_ldb);
321 if (!state->forest_dn) {
322 return NT_STATUS_NO_MEMORY;
325 ret = ldb_search(state->sam_ldb, state->domain_dn, LDB_SCOPE_BASE, NULL, dom_attrs, &dom_res);
327 if (ret != LDB_SUCCESS) {
328 return NT_STATUS_INVALID_SYSTEM_SERVICE;
330 talloc_steal(mem_ctx, dom_res);
331 if (dom_res->count != 1) {
332 return NT_STATUS_NO_SUCH_DOMAIN;
335 state->domain_sid = samdb_result_dom_sid(state, dom_res->msgs[0], "objectSid");
336 if (!state->domain_sid) {
337 return NT_STATUS_NO_SUCH_DOMAIN;
340 state->domain_guid = samdb_result_guid(dom_res->msgs[0], "objectGUID");
341 if (!state->domain_sid) {
342 return NT_STATUS_NO_SUCH_DOMAIN;
345 state->mixed_domain = ldb_msg_find_attr_as_uint(dom_res->msgs[0], "nTMixedDomain", 0);
347 talloc_free(dom_res);
349 ret = ldb_search_exp_fmt(state->sam_ldb, state, &ref_res,
350 partitions_basedn, LDB_SCOPE_SUBTREE, ref_attrs,
351 "(&(objectclass=crossRef)(ncName=%s))",
352 ldb_dn_get_linearized(state->domain_dn));
354 if (ret != LDB_SUCCESS) {
355 talloc_free(ref_res);
356 return NT_STATUS_INVALID_SYSTEM_SERVICE;
358 if (ref_res->count != 1) {
359 talloc_free(ref_res);
360 return NT_STATUS_NO_SUCH_DOMAIN;
363 state->domain_name = ldb_msg_find_attr_as_string(ref_res->msgs[0], "nETBIOSName", NULL);
364 if (!state->domain_name) {
365 talloc_free(ref_res);
366 return NT_STATUS_NO_SUCH_DOMAIN;
368 talloc_steal(state, state->domain_name);
370 state->domain_dns = ldb_msg_find_attr_as_string(ref_res->msgs[0], "dnsRoot", NULL);
371 if (!state->domain_dns) {
372 talloc_free(ref_res);
373 return NT_STATUS_NO_SUCH_DOMAIN;
375 talloc_steal(state, state->domain_dns);
377 talloc_free(ref_res);
379 ret = ldb_search_exp_fmt(state->sam_ldb, state, &forest_ref_res,
380 partitions_basedn, LDB_SCOPE_SUBTREE, ref_attrs,
381 "(&(objectclass=crossRef)(ncName=%s))",
382 ldb_dn_get_linearized(state->forest_dn));
384 if (ret != LDB_SUCCESS) {
385 talloc_free(forest_ref_res);
386 return NT_STATUS_INVALID_SYSTEM_SERVICE;
388 if (forest_ref_res->count != 1) {
389 talloc_free(forest_ref_res);
390 return NT_STATUS_NO_SUCH_DOMAIN;
393 state->forest_dns = ldb_msg_find_attr_as_string(forest_ref_res->msgs[0], "dnsRoot", NULL);
394 if (!state->forest_dns) {
395 talloc_free(forest_ref_res);
396 return NT_STATUS_NO_SUCH_DOMAIN;
398 talloc_steal(state, state->forest_dns);
400 talloc_free(forest_ref_res);
402 /* work out the builtin_dn - useful for so many calls its worth
404 state->builtin_dn = samdb_search_dn(state->sam_ldb, state, state->domain_dn, "(objectClass=builtinDomain)");
405 if (!state->builtin_dn) {
406 return NT_STATUS_NO_SUCH_DOMAIN;
409 /* work out the system_dn - useful for so many calls its worth
411 state->system_dn = samdb_search_dn(state->sam_ldb, state,
412 state->domain_dn, "(&(objectClass=container)(cn=System))");
413 if (!state->system_dn) {
414 return NT_STATUS_NO_SUCH_DOMAIN;
417 state->builtin_sid = dom_sid_parse_talloc(state, SID_BUILTIN);
418 if (!state->builtin_sid) {
419 return NT_STATUS_NO_SUCH_DOMAIN;
428 dssetup_DsRoleGetPrimaryDomainInformation
430 This is not an LSA call, but is the only call left on the DSSETUP
431 pipe (after the pipe was truncated), and needs lsa_get_policy_state
433 static WERROR dcesrv_dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state *dce_call,
435 struct dssetup_DsRoleGetPrimaryDomainInformation *r)
437 union dssetup_DsRoleInfo *info;
439 info = talloc(mem_ctx, union dssetup_DsRoleInfo);
440 W_ERROR_HAVE_NO_MEMORY(info);
442 switch (r->in.level) {
443 case DS_ROLE_BASIC_INFORMATION:
445 enum dssetup_DsRole role = DS_ROLE_STANDALONE_SERVER;
447 const char *domain = NULL;
448 const char *dns_domain = NULL;
449 const char *forest = NULL;
450 struct GUID domain_guid;
451 struct lsa_policy_state *state;
453 NTSTATUS status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
454 if (!NT_STATUS_IS_OK(status)) {
455 return ntstatus_to_werror(status);
458 ZERO_STRUCT(domain_guid);
460 switch (lp_server_role()) {
461 case ROLE_STANDALONE:
462 role = DS_ROLE_STANDALONE_SERVER;
464 case ROLE_DOMAIN_MEMBER:
465 role = DS_ROLE_MEMBER_SERVER;
467 case ROLE_DOMAIN_CONTROLLER:
468 if (samdb_is_pdc(state->sam_ldb)) {
469 role = DS_ROLE_PRIMARY_DC;
471 role = DS_ROLE_BACKUP_DC;
476 switch (lp_server_role()) {
477 case ROLE_STANDALONE:
478 domain = talloc_strdup(mem_ctx, lp_workgroup());
479 W_ERROR_HAVE_NO_MEMORY(domain);
481 case ROLE_DOMAIN_MEMBER:
482 domain = talloc_strdup(mem_ctx, lp_workgroup());
483 W_ERROR_HAVE_NO_MEMORY(domain);
484 /* TODO: what is with dns_domain and forest and guid? */
486 case ROLE_DOMAIN_CONTROLLER:
487 flags = DS_ROLE_PRIMARY_DS_RUNNING;
489 if (state->mixed_domain == 1) {
490 flags |= DS_ROLE_PRIMARY_DS_MIXED_MODE;
493 domain = state->domain_name;
494 dns_domain = state->domain_dns;
495 forest = state->forest_dns;
497 domain_guid = state->domain_guid;
498 flags |= DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT;
502 info->basic.role = role;
503 info->basic.flags = flags;
504 info->basic.domain = domain;
505 info->basic.dns_domain = dns_domain;
506 info->basic.forest = forest;
507 info->basic.domain_guid = domain_guid;
512 case DS_ROLE_UPGRADE_STATUS:
514 info->upgrade.upgrading = DS_ROLE_NOT_UPGRADING;
515 info->upgrade.previous_role = DS_ROLE_PREVIOUS_UNKNOWN;
520 case DS_ROLE_OP_STATUS:
522 info->opstatus.status = DS_ROLE_OP_IDLE;
528 return WERR_INVALID_PARAM;
531 return WERR_INVALID_PARAM;
537 static NTSTATUS dcesrv_lsa_OpenPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
538 struct lsa_OpenPolicy2 *r)
541 struct lsa_policy_state *state;
542 struct dcesrv_handle *handle;
544 ZERO_STRUCTP(r->out.handle);
546 status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
547 if (!NT_STATUS_IS_OK(status)) {
551 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_POLICY);
553 return NT_STATUS_NO_MEMORY;
556 handle->data = talloc_steal(handle, state);
558 state->access_mask = r->in.access_mask;
559 state->handle = handle;
560 *r->out.handle = handle->wire_handle;
562 /* note that we have completely ignored the attr element of
563 the OpenPolicy. As far as I can tell, this is what w2k3
571 a wrapper around lsa_OpenPolicy2
573 static NTSTATUS dcesrv_lsa_OpenPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
574 struct lsa_OpenPolicy *r)
576 struct lsa_OpenPolicy2 r2;
578 r2.in.system_name = NULL;
579 r2.in.attr = r->in.attr;
580 r2.in.access_mask = r->in.access_mask;
581 r2.out.handle = r->out.handle;
583 return dcesrv_lsa_OpenPolicy2(dce_call, mem_ctx, &r2);
590 fill in the AccountDomain info
592 static NTSTATUS dcesrv_lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
593 struct lsa_DomainInfo *info)
595 info->name.string = state->domain_name;
596 info->sid = state->domain_sid;
602 fill in the DNS domain info
604 static NTSTATUS dcesrv_lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
605 struct lsa_DnsDomainInfo *info)
607 info->name.string = state->domain_name;
608 info->sid = state->domain_sid;
609 info->dns_domain.string = state->domain_dns;
610 info->dns_forest.string = state->forest_dns;
611 info->domain_guid = state->domain_guid;
619 static NTSTATUS dcesrv_lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
620 struct lsa_QueryInfoPolicy2 *r)
622 struct lsa_policy_state *state;
623 struct dcesrv_handle *h;
627 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
631 r->out.info = talloc(mem_ctx, union lsa_PolicyInformation);
633 return NT_STATUS_NO_MEMORY;
636 ZERO_STRUCTP(r->out.info);
638 switch (r->in.level) {
639 case LSA_POLICY_INFO_DOMAIN:
640 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
641 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &r->out.info->account_domain);
643 case LSA_POLICY_INFO_DNS:
644 return dcesrv_lsa_info_DNS(state, mem_ctx, &r->out.info->dns);
647 return NT_STATUS_INVALID_INFO_CLASS;
653 static NTSTATUS dcesrv_lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
654 struct lsa_QueryInfoPolicy *r)
656 struct lsa_QueryInfoPolicy2 r2;
659 r2.in.handle = r->in.handle;
660 r2.in.level = r->in.level;
662 status = dcesrv_lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
664 r->out.info = r2.out.info;
672 static NTSTATUS dcesrv_lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
673 struct lsa_SetInfoPolicy *r)
675 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
682 static NTSTATUS dcesrv_lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
683 struct lsa_ClearAuditLog *r)
685 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
692 static NTSTATUS dcesrv_lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
693 struct lsa_CreateAccount *r)
695 struct lsa_account_state *astate;
697 struct lsa_policy_state *state;
698 struct dcesrv_handle *h, *ah;
700 ZERO_STRUCTP(r->out.acct_handle);
702 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
706 astate = talloc(dce_call->conn, struct lsa_account_state);
707 if (astate == NULL) {
708 return NT_STATUS_NO_MEMORY;
711 astate->account_sid = dom_sid_dup(astate, r->in.sid);
712 if (astate->account_sid == NULL) {
714 return NT_STATUS_NO_MEMORY;
717 astate->policy = talloc_reference(astate, state);
718 astate->access_mask = r->in.access_mask;
720 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
723 return NT_STATUS_NO_MEMORY;
726 ah->data = talloc_steal(ah, astate);
728 *r->out.acct_handle = ah->wire_handle;
737 static NTSTATUS dcesrv_lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
738 struct lsa_EnumAccounts *r)
740 struct dcesrv_handle *h;
741 struct lsa_policy_state *state;
743 struct ldb_message **res;
744 const char * const attrs[] = { "objectSid", NULL};
747 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
751 /* NOTE: This call must only return accounts that have at least
754 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
755 "(&(objectSid=*)(privilege=*))");
757 return NT_STATUS_NO_SUCH_USER;
760 if (*r->in.resume_handle >= ret) {
761 return NT_STATUS_NO_MORE_ENTRIES;
764 count = ret - *r->in.resume_handle;
765 if (count > r->in.num_entries) {
766 count = r->in.num_entries;
770 return NT_STATUS_NO_MORE_ENTRIES;
773 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, count);
774 if (r->out.sids->sids == NULL) {
775 return NT_STATUS_NO_MEMORY;
778 for (i=0;i<count;i++) {
779 r->out.sids->sids[i].sid =
780 samdb_result_dom_sid(r->out.sids->sids,
781 res[i + *r->in.resume_handle],
783 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
786 r->out.sids->num_sids = count;
787 *r->out.resume_handle = count + *r->in.resume_handle;
795 lsa_CreateTrustedDomainEx2
797 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
799 struct lsa_CreateTrustedDomainEx2 *r)
801 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
805 lsa_CreateTrustedDomainEx
807 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
809 struct lsa_CreateTrustedDomainEx *r)
811 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
815 lsa_CreateTrustedDomain
817 static NTSTATUS dcesrv_lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
818 struct lsa_CreateTrustedDomain *r)
820 struct dcesrv_handle *policy_handle;
821 struct lsa_policy_state *policy_state;
822 struct lsa_trusted_domain_state *trusted_domain_state;
823 struct dcesrv_handle *handle;
824 struct ldb_message **msgs, *msg;
825 const char *attrs[] = {
831 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
832 ZERO_STRUCTP(r->out.trustdom_handle);
834 policy_state = policy_handle->data;
836 if (!r->in.info->name.string) {
837 return NT_STATUS_INVALID_PARAMETER;
839 name = r->in.info->name.string;
841 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
842 if (!trusted_domain_state) {
843 return NT_STATUS_NO_MEMORY;
845 trusted_domain_state->policy = policy_state;
847 msg = ldb_msg_new(mem_ctx);
849 return NT_STATUS_NO_MEMORY;
852 /* search for the trusted_domain record */
853 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
854 mem_ctx, policy_state->system_dn, &msgs, attrs,
855 "(&(cn=%s)(objectclass=trustedDomain))",
856 ldb_binary_encode_string(mem_ctx, r->in.info->name.string));
858 return NT_STATUS_OBJECT_NAME_COLLISION;
861 if (ret < 0 || ret > 1) {
862 DEBUG(0,("Found %d records matching DN %s\n", ret,
863 ldb_dn_get_linearized(policy_state->system_dn)));
864 return NT_STATUS_INTERNAL_DB_CORRUPTION;
867 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
868 if ( ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name)) {
869 return NT_STATUS_NO_MEMORY;
872 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "flatname", name);
874 if (r->in.info->sid) {
875 const char *sid_string = dom_sid_string(mem_ctx, r->in.info->sid);
877 return NT_STATUS_NO_MEMORY;
880 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "securityIdentifier", sid_string);
883 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "objectClass", "trustedDomain");
885 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
887 /* create the trusted_domain */
888 ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg);
889 if (ret != LDB_SUCCESS) {
890 DEBUG(0,("Failed to create trusted_domain record %s: %s\n",
891 ldb_dn_get_linearized(msg->dn), ldb_errstring(trusted_domain_state->policy->sam_ldb)));
892 return NT_STATUS_INTERNAL_DB_CORRUPTION;
895 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
897 return NT_STATUS_NO_MEMORY;
900 handle->data = talloc_steal(handle, trusted_domain_state);
902 trusted_domain_state->access_mask = r->in.access_mask;
903 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
905 *r->out.trustdom_handle = handle->wire_handle;
911 lsa_OpenTrustedDomain
913 static NTSTATUS dcesrv_lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
914 struct lsa_OpenTrustedDomain *r)
916 struct dcesrv_handle *policy_handle;
918 struct lsa_policy_state *policy_state;
919 struct lsa_trusted_domain_state *trusted_domain_state;
920 struct dcesrv_handle *handle;
921 struct ldb_message **msgs;
922 const char *attrs[] = {
926 const char *sid_string;
929 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
930 ZERO_STRUCTP(r->out.trustdom_handle);
931 policy_state = policy_handle->data;
933 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
934 if (!trusted_domain_state) {
935 return NT_STATUS_NO_MEMORY;
937 trusted_domain_state->policy = policy_state;
939 sid_string = dom_sid_string(mem_ctx, r->in.sid);
941 return NT_STATUS_NO_MEMORY;
944 /* search for the trusted_domain record */
945 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
946 mem_ctx, policy_state->system_dn, &msgs, attrs,
947 "(&(securityIdentifier=%s)(objectclass=trustedDomain))",
950 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
954 DEBUG(0,("Found %d records matching DN %s\n", ret,
955 ldb_dn_get_linearized(policy_state->system_dn)));
956 return NT_STATUS_INTERNAL_DB_CORRUPTION;
959 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
961 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
963 return NT_STATUS_NO_MEMORY;
966 handle->data = talloc_steal(handle, trusted_domain_state);
968 trusted_domain_state->access_mask = r->in.access_mask;
969 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
971 *r->out.trustdom_handle = handle->wire_handle;
978 lsa_OpenTrustedDomainByName
980 static NTSTATUS dcesrv_lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
982 struct lsa_OpenTrustedDomainByName *r)
984 struct dcesrv_handle *policy_handle;
986 struct lsa_policy_state *policy_state;
987 struct lsa_trusted_domain_state *trusted_domain_state;
988 struct dcesrv_handle *handle;
989 struct ldb_message **msgs;
990 const char *attrs[] = {
996 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
997 ZERO_STRUCTP(r->out.trustdom_handle);
998 policy_state = policy_handle->data;
1000 if (!r->in.name.string) {
1001 return NT_STATUS_INVALID_PARAMETER;
1004 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
1005 if (!trusted_domain_state) {
1006 return NT_STATUS_NO_MEMORY;
1008 trusted_domain_state->policy = policy_state;
1010 /* search for the trusted_domain record */
1011 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1012 mem_ctx, policy_state->system_dn, &msgs, attrs,
1013 "(&(flatname=%s)(objectclass=trustedDomain))",
1014 ldb_binary_encode_string(mem_ctx, r->in.name.string));
1016 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1020 DEBUG(0,("Found %d records matching DN %s\n", ret,
1021 ldb_dn_get_linearized(policy_state->system_dn)));
1022 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1025 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
1027 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1029 return NT_STATUS_NO_MEMORY;
1032 handle->data = talloc_steal(handle, trusted_domain_state);
1034 trusted_domain_state->access_mask = r->in.access_mask;
1035 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1037 *r->out.trustdom_handle = handle->wire_handle;
1039 return NT_STATUS_OK;
1045 lsa_SetTrustedDomainInfo
1047 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1048 struct lsa_SetTrustedDomainInfo *r)
1050 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1056 lsa_SetInfomrationTrustedDomain
1058 static NTSTATUS dcesrv_lsa_SetInformationTrustedDomain(struct dcesrv_call_state *dce_call,
1059 TALLOC_CTX *mem_ctx,
1060 struct lsa_SetInformationTrustedDomain *r)
1062 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1067 lsa_DeleteTrustedDomain
1069 static NTSTATUS dcesrv_lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1070 struct lsa_DeleteTrustedDomain *r)
1073 struct lsa_OpenTrustedDomain open;
1074 struct lsa_Delete delete;
1075 struct dcesrv_handle *h;
1077 open.in.handle = r->in.handle;
1078 open.in.sid = r->in.dom_sid;
1079 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1080 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1081 if (!open.out.trustdom_handle) {
1082 return NT_STATUS_NO_MEMORY;
1084 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
1085 if (!NT_STATUS_IS_OK(status)) {
1089 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1090 talloc_steal(mem_ctx, h);
1092 delete.in.handle = open.out.trustdom_handle;
1093 status = dcesrv_lsa_Delete(dce_call, mem_ctx, &delete);
1094 if (!NT_STATUS_IS_OK(status)) {
1097 return NT_STATUS_OK;
1100 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx,
1101 struct ldb_message *msg,
1102 struct lsa_TrustDomainInfoInfoEx *info_ex)
1104 info_ex->domain_name.string
1105 = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
1106 info_ex->netbios_name.string
1107 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1109 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1110 info_ex->trust_direction
1111 = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
1113 = ldb_msg_find_attr_as_int(msg, "trustType", 0);
1114 info_ex->trust_attributes
1115 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);
1116 return NT_STATUS_OK;
1120 lsa_QueryTrustedDomainInfo
1122 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1123 struct lsa_QueryTrustedDomainInfo *r)
1125 struct dcesrv_handle *h;
1126 struct lsa_trusted_domain_state *trusted_domain_state;
1127 struct ldb_message *msg;
1129 struct ldb_message **res;
1130 const char *attrs[] = {
1133 "securityIdentifier",
1140 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
1142 trusted_domain_state = h->data;
1144 /* pull all the user attributes */
1145 ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
1146 trusted_domain_state->trusted_domain_dn, &res, attrs);
1148 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1152 r->out.info = talloc(mem_ctx, union lsa_TrustedDomainInfo);
1154 return NT_STATUS_NO_MEMORY;
1156 switch (r->in.level) {
1157 case LSA_TRUSTED_DOMAIN_INFO_NAME:
1158 r->out.info->name.netbios_name.string
1159 = samdb_result_string(msg, "flatname", NULL);
1161 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1162 r->out.info->posix_offset.posix_offset
1163 = samdb_result_uint(msg, "posixOffset", 0);
1165 #if 0 /* Win2k3 doesn't implement this */
1166 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
1167 r->out.info->info_basic.netbios_name.string
1168 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1169 r->out.info->info_basic.sid
1170 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1173 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1174 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->info_ex);
1176 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1177 ZERO_STRUCT(r->out.info->full_info);
1178 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->full_info.info_ex);
1180 case LSA_TRUSTED_DOMAIN_INFO_INFO_ALL:
1181 ZERO_STRUCT(r->out.info->info_all);
1182 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->info_all.info_ex);
1184 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS_INFO:
1185 case LSA_TRUSTED_DOMAIN_INFO_11:
1186 /* oops, we don't want to return the info after all */
1187 talloc_free(r->out.info);
1189 return NT_STATUS_INVALID_PARAMETER;
1191 /* oops, we don't want to return the info after all */
1192 talloc_free(r->out.info);
1194 return NT_STATUS_INVALID_INFO_CLASS;
1197 return NT_STATUS_OK;
1202 lsa_QueryTrustedDomainInfoBySid
1204 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1205 struct lsa_QueryTrustedDomainInfoBySid *r)
1208 struct lsa_OpenTrustedDomain open;
1209 struct lsa_QueryTrustedDomainInfo query;
1210 struct dcesrv_handle *h;
1211 open.in.handle = r->in.handle;
1212 open.in.sid = r->in.dom_sid;
1213 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1214 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1215 if (!open.out.trustdom_handle) {
1216 return NT_STATUS_NO_MEMORY;
1218 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
1219 if (!NT_STATUS_IS_OK(status)) {
1223 /* Ensure this handle goes away at the end of this call */
1224 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1225 talloc_steal(mem_ctx, h);
1227 query.in.trustdom_handle = open.out.trustdom_handle;
1228 query.in.level = r->in.level;
1229 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1230 if (!NT_STATUS_IS_OK(status)) {
1234 r->out.info = query.out.info;
1235 return NT_STATUS_OK;
1239 lsa_SetTrustedDomainInfoByName
1241 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1242 TALLOC_CTX *mem_ctx,
1243 struct lsa_SetTrustedDomainInfoByName *r)
1245 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1249 lsa_QueryTrustedDomainInfoByName
1251 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1252 TALLOC_CTX *mem_ctx,
1253 struct lsa_QueryTrustedDomainInfoByName *r)
1256 struct lsa_OpenTrustedDomainByName open;
1257 struct lsa_QueryTrustedDomainInfo query;
1258 struct dcesrv_handle *h;
1259 open.in.handle = r->in.handle;
1260 open.in.name = r->in.trusted_domain;
1261 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1262 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1263 if (!open.out.trustdom_handle) {
1264 return NT_STATUS_NO_MEMORY;
1266 status = dcesrv_lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &open);
1267 if (!NT_STATUS_IS_OK(status)) {
1271 /* Ensure this handle goes away at the end of this call */
1272 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1273 talloc_steal(mem_ctx, h);
1275 query.in.trustdom_handle = open.out.trustdom_handle;
1276 query.in.level = r->in.level;
1277 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1278 if (!NT_STATUS_IS_OK(status)) {
1282 r->out.info = query.out.info;
1283 return NT_STATUS_OK;
1287 lsa_CloseTrustedDomainEx
1289 static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
1290 TALLOC_CTX *mem_ctx,
1291 struct lsa_CloseTrustedDomainEx *r)
1293 /* The result of a bad hair day from an IDL programmer? Not
1294 * implmented in Win2k3. You should always just lsa_Close
1296 return NT_STATUS_NOT_IMPLEMENTED;
1301 comparison function for sorting lsa_DomainInformation array
1303 static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
1305 return strcasecmp_m(e1->name.string, e2->name.string);
1311 static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1312 struct lsa_EnumTrustDom *r)
1314 struct dcesrv_handle *policy_handle;
1315 struct lsa_DomainInfo *entries;
1316 struct lsa_policy_state *policy_state;
1317 struct ldb_message **domains;
1318 const char *attrs[] = {
1320 "securityIdentifier",
1327 *r->out.resume_handle = 0;
1329 r->out.domains->domains = NULL;
1330 r->out.domains->count = 0;
1332 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1334 policy_state = policy_handle->data;
1336 /* search for all users in this domain. This could possibly be cached and
1337 resumed based on resume_key */
1338 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1339 "objectclass=trustedDomain");
1341 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1343 if (count == 0 || r->in.max_size == 0) {
1344 return NT_STATUS_OK;
1347 /* convert to lsa_TrustInformation format */
1348 entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
1350 return NT_STATUS_NO_MEMORY;
1352 for (i=0;i<count;i++) {
1353 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
1354 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
1357 /* sort the results by name */
1358 qsort(entries, count, sizeof(*entries),
1359 (comparison_fn_t)compare_DomainInfo);
1361 if (*r->in.resume_handle >= count) {
1362 *r->out.resume_handle = -1;
1364 return NT_STATUS_NO_MORE_ENTRIES;
1367 /* return the rest, limit by max_size. Note that we
1368 use the w2k3 element size value of 60 */
1369 r->out.domains->count = count - *r->in.resume_handle;
1370 r->out.domains->count = MIN(r->out.domains->count,
1371 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
1373 r->out.domains->domains = entries + *r->in.resume_handle;
1374 r->out.domains->count = r->out.domains->count;
1376 if (r->out.domains->count < count - *r->in.resume_handle) {
1377 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1378 return STATUS_MORE_ENTRIES;
1381 return NT_STATUS_OK;
1385 comparison function for sorting lsa_DomainInformation array
1387 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
1389 return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
1393 lsa_EnumTrustedDomainsEx
1395 static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1396 struct lsa_EnumTrustedDomainsEx *r)
1398 struct dcesrv_handle *policy_handle;
1399 struct lsa_TrustDomainInfoInfoEx *entries;
1400 struct lsa_policy_state *policy_state;
1401 struct ldb_message **domains;
1402 const char *attrs[] = {
1405 "securityIdentifier",
1415 *r->out.resume_handle = 0;
1417 r->out.domains->domains = NULL;
1418 r->out.domains->count = 0;
1420 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1422 policy_state = policy_handle->data;
1424 /* search for all users in this domain. This could possibly be cached and
1425 resumed based on resume_key */
1426 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1427 "objectclass=trustedDomain");
1429 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1431 if (count == 0 || r->in.max_size == 0) {
1432 return NT_STATUS_OK;
1435 /* convert to lsa_DomainInformation format */
1436 entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
1438 return NT_STATUS_NO_MEMORY;
1440 for (i=0;i<count;i++) {
1441 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
1442 if (!NT_STATUS_IS_OK(nt_status)) {
1447 /* sort the results by name */
1448 qsort(entries, count, sizeof(*entries),
1449 (comparison_fn_t)compare_TrustDomainInfoInfoEx);
1451 if (*r->in.resume_handle >= count) {
1452 *r->out.resume_handle = -1;
1454 return NT_STATUS_NO_MORE_ENTRIES;
1457 /* return the rest, limit by max_size. Note that we
1458 use the w2k3 element size value of 60 */
1459 r->out.domains->count = count - *r->in.resume_handle;
1460 r->out.domains->count = MIN(r->out.domains->count,
1461 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
1463 r->out.domains->domains = entries + *r->in.resume_handle;
1464 r->out.domains->count = r->out.domains->count;
1466 if (r->out.domains->count < count - *r->in.resume_handle) {
1467 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1468 return STATUS_MORE_ENTRIES;
1471 return NT_STATUS_OK;
1476 return the authority name and authority sid, given a sid
1478 static NTSTATUS dcesrv_lsa_authority_name(struct lsa_policy_state *state,
1479 TALLOC_CTX *mem_ctx, struct dom_sid *sid,
1480 const char **authority_name,
1481 struct dom_sid **authority_sid)
1483 if (dom_sid_in_domain(state->domain_sid, sid)) {
1484 *authority_name = state->domain_name;
1485 *authority_sid = state->domain_sid;
1486 return NT_STATUS_OK;
1489 if (dom_sid_in_domain(state->builtin_sid, sid)) {
1490 *authority_name = "BUILTIN";
1491 *authority_sid = state->builtin_sid;
1492 return NT_STATUS_OK;
1495 *authority_sid = dom_sid_dup(mem_ctx, sid);
1496 if (*authority_sid == NULL) {
1497 return NT_STATUS_NO_MEMORY;
1499 (*authority_sid)->num_auths = 0;
1500 *authority_name = dom_sid_string(mem_ctx, *authority_sid);
1501 if (*authority_name == NULL) {
1502 return NT_STATUS_NO_MEMORY;
1505 return NT_STATUS_OK;
1509 add to the lsa_RefDomainList for LookupSids and LookupNames
1511 static NTSTATUS dcesrv_lsa_authority_list(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
1512 struct dom_sid *sid,
1513 struct lsa_RefDomainList *domains,
1514 uint32_t *sid_index)
1517 const char *authority_name;
1518 struct dom_sid *authority_sid;
1521 /* work out the authority name */
1522 status = dcesrv_lsa_authority_name(state, mem_ctx, sid,
1523 &authority_name, &authority_sid);
1524 if (!NT_STATUS_IS_OK(status)) {
1528 /* see if we've already done this authority name */
1529 for (i=0;i<domains->count;i++) {
1530 if (strcmp(authority_name, domains->domains[i].name.string) == 0) {
1532 return NT_STATUS_OK;
1536 domains->domains = talloc_realloc(domains,
1538 struct lsa_DomainInfo,
1540 if (domains->domains == NULL) {
1541 return NT_STATUS_NO_MEMORY;
1543 domains->domains[i].name.string = authority_name;
1544 domains->domains[i].sid = authority_sid;
1546 domains->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER * domains->count;
1549 return NT_STATUS_OK;
1553 lookup a name for 1 SID
1555 static NTSTATUS dcesrv_lsa_lookup_sid(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
1556 struct dom_sid *sid, const char *sid_str,
1557 const char **name, uint32_t *atype)
1560 struct ldb_message **res;
1561 const char * const attrs[] = { "sAMAccountName", "sAMAccountType", "name", NULL};
1564 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
1565 "objectSid=%s", ldap_encode_ndr_dom_sid(mem_ctx, sid));
1567 *name = ldb_msg_find_attr_as_string(res[0], "sAMAccountName", NULL);
1569 *name = ldb_msg_find_attr_as_string(res[0], "name", NULL);
1571 *name = talloc_strdup(mem_ctx, sid_str);
1572 NT_STATUS_HAVE_NO_MEMORY(*name);
1576 *atype = samdb_result_uint(res[0], "sAMAccountType", 0);
1578 return NT_STATUS_OK;
1581 status = sidmap_allocated_sid_lookup(state->sidmap, mem_ctx, sid, name, atype);
1590 static NTSTATUS dcesrv_lsa_LookupSids2(struct dcesrv_call_state *dce_call,
1591 TALLOC_CTX *mem_ctx,
1592 struct lsa_LookupSids2 *r)
1594 struct lsa_policy_state *state;
1596 NTSTATUS status = NT_STATUS_OK;
1598 r->out.domains = NULL;
1600 status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
1601 if (!NT_STATUS_IS_OK(status)) {
1605 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
1606 if (r->out.domains == NULL) {
1607 return NT_STATUS_NO_MEMORY;
1610 r->out.names = talloc_zero(mem_ctx, struct lsa_TransNameArray2);
1611 if (r->out.names == NULL) {
1612 return NT_STATUS_NO_MEMORY;
1617 r->out.names->names = talloc_array(r->out.names, struct lsa_TranslatedName2,
1618 r->in.sids->num_sids);
1619 if (r->out.names->names == NULL) {
1620 return NT_STATUS_NO_MEMORY;
1623 for (i=0;i<r->in.sids->num_sids;i++) {
1624 struct dom_sid *sid = r->in.sids->sids[i].sid;
1625 char *sid_str = dom_sid_string(mem_ctx, sid);
1627 uint32_t atype, rtype, sid_index;
1630 r->out.names->count++;
1633 r->out.names->names[i].sid_type = SID_NAME_UNKNOWN;
1634 r->out.names->names[i].name.string = sid_str;
1635 r->out.names->names[i].sid_index = 0xFFFFFFFF;
1636 r->out.names->names[i].unknown = 0;
1638 if (sid_str == NULL) {
1639 r->out.names->names[i].name.string = "(SIDERROR)";
1640 status = STATUS_SOME_UNMAPPED;
1644 /* work out the authority name */
1645 status2 = dcesrv_lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
1646 if (!NT_STATUS_IS_OK(status2)) {
1650 status2 = dcesrv_lsa_lookup_sid(state, mem_ctx, sid, sid_str,
1652 if (!NT_STATUS_IS_OK(status2)) {
1653 status = STATUS_SOME_UNMAPPED;
1657 rtype = samdb_atype_map(atype);
1658 if (rtype == SID_NAME_UNKNOWN) {
1659 status = STATUS_SOME_UNMAPPED;
1663 r->out.names->names[i].sid_type = rtype;
1664 r->out.names->names[i].name.string = name;
1665 r->out.names->names[i].sid_index = sid_index;
1666 r->out.names->names[i].unknown = 0;
1676 Identical to LookupSids2, but doesn't take a policy handle
1679 static NTSTATUS dcesrv_lsa_LookupSids3(struct dcesrv_call_state *dce_call,
1680 TALLOC_CTX *mem_ctx,
1681 struct lsa_LookupSids3 *r)
1683 struct lsa_LookupSids2 r2;
1684 struct lsa_OpenPolicy2 pol;
1686 struct dcesrv_handle *h;
1688 /* No policy handle on the wire, so make one up here */
1689 r2.in.handle = talloc(mem_ctx, struct policy_handle);
1690 if (!r2.in.handle) {
1691 return NT_STATUS_NO_MEMORY;
1694 pol.out.handle = r2.in.handle;
1695 pol.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1697 pol.in.system_name = NULL;
1698 status = dcesrv_lsa_OpenPolicy2(dce_call, mem_ctx, &pol);
1699 if (!NT_STATUS_IS_OK(status)) {
1703 /* ensure this handle goes away at the end of this call */
1704 DCESRV_PULL_HANDLE(h, r2.in.handle, LSA_HANDLE_POLICY);
1705 talloc_steal(mem_ctx, h);
1707 r2.in.sids = r->in.sids;
1708 r2.in.names = r->in.names;
1709 r2.in.level = r->in.level;
1710 r2.in.count = r->in.count;
1711 r2.in.unknown1 = r->in.unknown1;
1712 r2.in.unknown2 = r->in.unknown2;
1713 r2.out.count = r->out.count;
1714 r2.out.names = r->out.names;
1716 status = dcesrv_lsa_LookupSids2(dce_call, mem_ctx, &r2);
1717 if (dce_call->fault_code != 0) {
1721 r->out.domains = r2.out.domains;
1722 r->out.names = r2.out.names;
1723 r->out.count = r2.out.count;
1732 static NTSTATUS dcesrv_lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1733 struct lsa_LookupSids *r)
1735 struct lsa_LookupSids2 r2;
1739 r2.in.handle = r->in.handle;
1740 r2.in.sids = r->in.sids;
1742 r2.in.level = r->in.level;
1743 r2.in.count = r->in.count;
1746 r2.out.count = r->out.count;
1747 r2.out.names = NULL;
1749 status = dcesrv_lsa_LookupSids2(dce_call, mem_ctx, &r2);
1750 if (dce_call->fault_code != 0) {
1754 r->out.domains = r2.out.domains;
1755 if (!r2.out.names) {
1756 r->out.names = NULL;
1760 r->out.names = talloc(mem_ctx, struct lsa_TransNameArray);
1761 if (r->out.names == NULL) {
1762 return NT_STATUS_NO_MEMORY;
1764 r->out.names->count = r2.out.names->count;
1765 r->out.names->names = talloc_array(r->out.names, struct lsa_TranslatedName,
1766 r->out.names->count);
1767 if (r->out.names->names == NULL) {
1768 return NT_STATUS_NO_MEMORY;
1770 for (i=0;i<r->out.names->count;i++) {
1771 r->out.names->names[i].sid_type = r2.out.names->names[i].sid_type;
1772 r->out.names->names[i].name.string = r2.out.names->names[i].name.string;
1773 r->out.names->names[i].sid_index = r2.out.names->names[i].sid_index;
1783 static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1784 struct lsa_OpenAccount *r)
1786 struct dcesrv_handle *h, *ah;
1787 struct lsa_policy_state *state;
1788 struct lsa_account_state *astate;
1790 ZERO_STRUCTP(r->out.acct_handle);
1792 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1796 astate = talloc(dce_call->conn, struct lsa_account_state);
1797 if (astate == NULL) {
1798 return NT_STATUS_NO_MEMORY;
1801 astate->account_sid = dom_sid_dup(astate, r->in.sid);
1802 if (astate->account_sid == NULL) {
1803 talloc_free(astate);
1804 return NT_STATUS_NO_MEMORY;
1807 astate->policy = talloc_reference(astate, state);
1808 astate->access_mask = r->in.access_mask;
1810 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
1812 talloc_free(astate);
1813 return NT_STATUS_NO_MEMORY;
1816 ah->data = talloc_steal(ah, astate);
1818 *r->out.acct_handle = ah->wire_handle;
1820 return NT_STATUS_OK;
1825 lsa_EnumPrivsAccount
1827 static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
1828 TALLOC_CTX *mem_ctx,
1829 struct lsa_EnumPrivsAccount *r)
1831 struct dcesrv_handle *h;
1832 struct lsa_account_state *astate;
1834 struct ldb_message **res;
1835 const char * const attrs[] = { "privilege", NULL};
1836 struct ldb_message_element *el;
1839 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1843 r->out.privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
1844 r->out.privs->count = 0;
1845 r->out.privs->unknown = 0;
1846 r->out.privs->set = NULL;
1848 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
1849 if (sidstr == NULL) {
1850 return NT_STATUS_NO_MEMORY;
1853 ret = gendb_search(astate->policy->sam_ldb, mem_ctx, NULL, &res, attrs,
1854 "objectSid=%s", sidstr);
1856 return NT_STATUS_OK;
1859 el = ldb_msg_find_element(res[0], "privilege");
1860 if (el == NULL || el->num_values == 0) {
1861 return NT_STATUS_OK;
1864 r->out.privs->set = talloc_array(r->out.privs,
1865 struct lsa_LUIDAttribute, el->num_values);
1866 if (r->out.privs->set == NULL) {
1867 return NT_STATUS_NO_MEMORY;
1870 for (i=0;i<el->num_values;i++) {
1871 int id = sec_privilege_id((const char *)el->values[i].data);
1873 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1875 r->out.privs->set[i].attribute = 0;
1876 r->out.privs->set[i].luid.low = id;
1877 r->out.privs->set[i].luid.high = 0;
1880 r->out.privs->count = el->num_values;
1882 return NT_STATUS_OK;
1886 lsa_EnumAccountRights
1888 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
1889 TALLOC_CTX *mem_ctx,
1890 struct lsa_EnumAccountRights *r)
1892 struct dcesrv_handle *h;
1893 struct lsa_policy_state *state;
1895 struct ldb_message **res;
1896 const char * const attrs[] = { "privilege", NULL};
1898 struct ldb_message_element *el;
1900 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1904 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
1905 if (sidstr == NULL) {
1906 return NT_STATUS_NO_MEMORY;
1909 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
1910 "(&(objectSid=%s)(privilege=*))", sidstr);
1912 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1915 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1918 DEBUG(3, ("searching for account rights for SID: %s failed: %s",
1919 dom_sid_string(mem_ctx, r->in.sid),
1920 ldb_errstring(state->sam_ldb)));
1921 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1924 el = ldb_msg_find_element(res[0], "privilege");
1925 if (el == NULL || el->num_values == 0) {
1926 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1929 r->out.rights->count = el->num_values;
1930 r->out.rights->names = talloc_array(r->out.rights,
1931 struct lsa_StringLarge, r->out.rights->count);
1932 if (r->out.rights->names == NULL) {
1933 return NT_STATUS_NO_MEMORY;
1936 for (i=0;i<el->num_values;i++) {
1937 r->out.rights->names[i].string = (const char *)el->values[i].data;
1940 return NT_STATUS_OK;
1946 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
1948 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
1949 TALLOC_CTX *mem_ctx,
1950 struct lsa_policy_state *state,
1952 struct dom_sid *sid,
1953 const struct lsa_RightSet *rights)
1956 struct ldb_message *msg;
1957 struct ldb_message_element *el;
1959 struct lsa_EnumAccountRights r2;
1961 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, sid);
1962 if (sidstr == NULL) {
1963 return NT_STATUS_NO_MEMORY;
1966 msg = ldb_msg_new(mem_ctx);
1968 return NT_STATUS_NO_MEMORY;
1971 msg->dn = samdb_search_dn(state->sam_ldb, mem_ctx,
1972 NULL, "objectSid=%s", sidstr);
1973 if (msg->dn == NULL) {
1975 if (ldb_flag == LDB_FLAG_MOD_DELETE) {
1976 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1978 status = samdb_create_foreign_security_principal(state->sam_ldb, mem_ctx,
1980 if (!NT_STATUS_IS_OK(status)) {
1983 return NT_STATUS_NO_SUCH_USER;
1986 if (ldb_msg_add_empty(msg, "privilege", ldb_flag, NULL)) {
1987 return NT_STATUS_NO_MEMORY;
1990 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1993 r2.in.handle = &state->handle->wire_handle;
1995 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
1997 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1998 if (!NT_STATUS_IS_OK(status)) {
1999 ZERO_STRUCTP(r2.out.rights);
2003 for (i=0;i<rights->count;i++) {
2004 if (sec_privilege_id(rights->names[i].string) == -1) {
2005 return NT_STATUS_NO_SUCH_PRIVILEGE;
2008 if (ldb_flag == LDB_FLAG_MOD_ADD) {
2010 for (j=0;j<r2.out.rights->count;j++) {
2011 if (strcasecmp_m(r2.out.rights->names[j].string,
2012 rights->names[i].string) == 0) {
2016 if (j != r2.out.rights->count) continue;
2019 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
2020 if (ret != LDB_SUCCESS) {
2021 return NT_STATUS_NO_MEMORY;
2025 el = ldb_msg_find_element(msg, "privilege");
2027 return NT_STATUS_OK;
2030 ret = samdb_modify(state->sam_ldb, mem_ctx, msg);
2032 if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
2033 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2035 DEBUG(3, ("Could not %s attributes from %s: %s",
2036 ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add",
2037 ldb_dn_get_linearized(msg->dn), ldb_errstring(state->sam_ldb)));
2038 return NT_STATUS_UNEXPECTED_IO_ERROR;
2041 return NT_STATUS_OK;
2045 lsa_AddPrivilegesToAccount
2047 static NTSTATUS dcesrv_lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2048 struct lsa_AddPrivilegesToAccount *r)
2050 struct lsa_RightSet rights;
2051 struct dcesrv_handle *h;
2052 struct lsa_account_state *astate;
2055 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2059 rights.count = r->in.privs->count;
2060 rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
2061 if (rights.names == NULL) {
2062 return NT_STATUS_NO_MEMORY;
2064 for (i=0;i<rights.count;i++) {
2065 int id = r->in.privs->set[i].luid.low;
2066 if (r->in.privs->set[i].luid.high) {
2067 return NT_STATUS_NO_SUCH_PRIVILEGE;
2069 rights.names[i].string = sec_privilege_name(id);
2070 if (rights.names[i].string == NULL) {
2071 return NT_STATUS_NO_SUCH_PRIVILEGE;
2075 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2076 LDB_FLAG_MOD_ADD, astate->account_sid,
2082 lsa_RemovePrivilegesFromAccount
2084 static NTSTATUS dcesrv_lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2085 struct lsa_RemovePrivilegesFromAccount *r)
2087 struct lsa_RightSet *rights;
2088 struct dcesrv_handle *h;
2089 struct lsa_account_state *astate;
2092 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2096 rights = talloc(mem_ctx, struct lsa_RightSet);
2098 if (r->in.remove_all == 1 &&
2099 r->in.privs == NULL) {
2100 struct lsa_EnumAccountRights r2;
2103 r2.in.handle = &astate->policy->handle->wire_handle;
2104 r2.in.sid = astate->account_sid;
2105 r2.out.rights = rights;
2107 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
2108 if (!NT_STATUS_IS_OK(status)) {
2112 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2113 LDB_FLAG_MOD_DELETE, astate->account_sid,
2117 if (r->in.remove_all != 0) {
2118 return NT_STATUS_INVALID_PARAMETER;
2121 rights->count = r->in.privs->count;
2122 rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
2123 if (rights->names == NULL) {
2124 return NT_STATUS_NO_MEMORY;
2126 for (i=0;i<rights->count;i++) {
2127 int id = r->in.privs->set[i].luid.low;
2128 if (r->in.privs->set[i].luid.high) {
2129 return NT_STATUS_NO_SUCH_PRIVILEGE;
2131 rights->names[i].string = sec_privilege_name(id);
2132 if (rights->names[i].string == NULL) {
2133 return NT_STATUS_NO_SUCH_PRIVILEGE;
2137 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2138 LDB_FLAG_MOD_DELETE, astate->account_sid,
2144 lsa_GetQuotasForAccount
2146 static NTSTATUS dcesrv_lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2147 struct lsa_GetQuotasForAccount *r)
2149 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2154 lsa_SetQuotasForAccount
2156 static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2157 struct lsa_SetQuotasForAccount *r)
2159 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2164 lsa_GetSystemAccessAccount
2166 static NTSTATUS dcesrv_lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2167 struct lsa_GetSystemAccessAccount *r)
2169 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2174 lsa_SetSystemAccessAccount
2176 static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2177 struct lsa_SetSystemAccessAccount *r)
2179 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2186 static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2187 struct lsa_CreateSecret *r)
2189 struct dcesrv_handle *policy_handle;
2190 struct lsa_policy_state *policy_state;
2191 struct lsa_secret_state *secret_state;
2192 struct dcesrv_handle *handle;
2193 struct ldb_message **msgs, *msg;
2195 const char *attrs[] = {
2203 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2204 ZERO_STRUCTP(r->out.sec_handle);
2206 policy_state = policy_handle->data;
2208 if (!r->in.name.string) {
2209 return NT_STATUS_INVALID_PARAMETER;
2212 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2213 if (!secret_state) {
2214 return NT_STATUS_NO_MEMORY;
2216 secret_state->policy = policy_state;
2218 msg = ldb_msg_new(mem_ctx);
2220 return NT_STATUS_NO_MEMORY;
2223 if (strncmp("G$", r->in.name.string, 2) == 0) {
2225 name = &r->in.name.string[2];
2226 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
2227 secret_state->global = True;
2229 if (strlen(name) < 1) {
2230 return NT_STATUS_INVALID_PARAMETER;
2233 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
2234 /* search for the secret record */
2235 ret = gendb_search(secret_state->sam_ldb,
2236 mem_ctx, policy_state->system_dn, &msgs, attrs,
2237 "(&(cn=%s)(objectclass=secret))",
2240 return NT_STATUS_OBJECT_NAME_COLLISION;
2244 DEBUG(0,("Failure searching for CN=%s: %s\n",
2245 name2, ldb_errstring(secret_state->sam_ldb)));
2246 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2249 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
2250 if (!name2 || ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
2251 return NT_STATUS_NO_MEMORY;
2254 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
2257 secret_state->global = False;
2259 name = r->in.name.string;
2260 if (strlen(name) < 1) {
2261 return NT_STATUS_INVALID_PARAMETER;
2264 secret_state->sam_ldb = talloc_reference(secret_state, secrets_db_connect(mem_ctx));
2265 /* search for the secret record */
2266 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2267 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2269 "(&(cn=%s)(objectclass=secret))",
2270 ldb_binary_encode_string(mem_ctx, name));
2272 return NT_STATUS_OBJECT_NAME_COLLISION;
2276 DEBUG(0,("Failure searching for CN=%s: %s\n",
2277 name, ldb_errstring(secret_state->sam_ldb)));
2278 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2281 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name);
2282 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
2285 /* pull in all the template attributes. Note this is always from the global samdb */
2286 ret = samdb_copy_template(secret_state->policy->sam_ldb, msg,
2289 DEBUG(0,("Failed to load TemplateSecret from samdb: %s\n",
2291 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2294 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
2296 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
2298 /* create the secret */
2299 ret = samdb_add(secret_state->sam_ldb, mem_ctx, msg);
2301 DEBUG(0,("Failed to create secret record %s: %s\n",
2302 ldb_dn_get_linearized(msg->dn),
2303 ldb_errstring(secret_state->sam_ldb)));
2304 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2307 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2309 return NT_STATUS_NO_MEMORY;
2312 handle->data = talloc_steal(handle, secret_state);
2314 secret_state->access_mask = r->in.access_mask;
2315 secret_state->policy = talloc_reference(secret_state, policy_state);
2317 *r->out.sec_handle = handle->wire_handle;
2319 return NT_STATUS_OK;
2326 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2327 struct lsa_OpenSecret *r)
2329 struct dcesrv_handle *policy_handle;
2331 struct lsa_policy_state *policy_state;
2332 struct lsa_secret_state *secret_state;
2333 struct dcesrv_handle *handle;
2334 struct ldb_message **msgs;
2335 const char *attrs[] = {
2343 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2344 ZERO_STRUCTP(r->out.sec_handle);
2345 policy_state = policy_handle->data;
2347 if (!r->in.name.string) {
2348 return NT_STATUS_INVALID_PARAMETER;
2351 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2352 if (!secret_state) {
2353 return NT_STATUS_NO_MEMORY;
2355 secret_state->policy = policy_state;
2357 if (strncmp("G$", r->in.name.string, 2) == 0) {
2358 name = &r->in.name.string[2];
2359 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
2360 secret_state->global = True;
2362 if (strlen(name) < 1) {
2363 return NT_STATUS_INVALID_PARAMETER;
2366 /* search for the secret record */
2367 ret = gendb_search(secret_state->sam_ldb,
2368 mem_ctx, policy_state->system_dn, &msgs, attrs,
2369 "(&(cn=%s Secret)(objectclass=secret))",
2370 ldb_binary_encode_string(mem_ctx, name));
2372 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2376 DEBUG(0,("Found %d records matching DN %s\n", ret,
2377 ldb_dn_get_linearized(policy_state->system_dn)));
2378 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2382 secret_state->sam_ldb = talloc_reference(secret_state, secrets_db_connect(mem_ctx));
2384 secret_state->global = False;
2385 name = r->in.name.string;
2386 if (strlen(name) < 1) {
2387 return NT_STATUS_INVALID_PARAMETER;
2390 /* search for the secret record */
2391 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2392 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2394 "(&(cn=%s)(objectclass=secret))",
2395 ldb_binary_encode_string(mem_ctx, name));
2397 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2401 DEBUG(0,("Found %d records matching DN %s\n", ret,
2402 ldb_dn_get_linearized(policy_state->system_dn)));
2403 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2407 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
2409 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2411 return NT_STATUS_NO_MEMORY;
2414 handle->data = talloc_steal(handle, secret_state);
2416 secret_state->access_mask = r->in.access_mask;
2417 secret_state->policy = talloc_reference(secret_state, policy_state);
2419 *r->out.sec_handle = handle->wire_handle;
2421 return NT_STATUS_OK;
2428 static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2429 struct lsa_SetSecret *r)
2432 struct dcesrv_handle *h;
2433 struct lsa_secret_state *secret_state;
2434 struct ldb_message *msg;
2435 DATA_BLOB session_key;
2436 DATA_BLOB crypt_secret, secret;
2439 NTSTATUS status = NT_STATUS_OK;
2441 struct timeval now = timeval_current();
2442 NTTIME nt_now = timeval_to_nttime(&now);
2444 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2446 secret_state = h->data;
2448 msg = ldb_msg_new(mem_ctx);
2450 return NT_STATUS_NO_MEMORY;
2453 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
2455 return NT_STATUS_NO_MEMORY;
2457 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2458 if (!NT_STATUS_IS_OK(status)) {
2462 if (r->in.old_val) {
2464 crypt_secret.data = r->in.old_val->data;
2465 crypt_secret.length = r->in.old_val->size;
2467 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2468 if (!NT_STATUS_IS_OK(status)) {
2472 val.data = secret.data;
2473 val.length = secret.length;
2476 if (samdb_msg_add_value(secret_state->sam_ldb,
2477 mem_ctx, msg, "priorValue", &val) != 0) {
2478 return NT_STATUS_NO_MEMORY;
2481 /* set old value mtime */
2482 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2483 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
2484 return NT_STATUS_NO_MEMORY;
2487 if (!r->in.new_val) {
2488 /* This behaviour varies depending of if this is a local, or a global secret... */
2489 if (secret_state->global) {
2490 /* set old value mtime */
2491 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2492 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2493 return NT_STATUS_NO_MEMORY;
2496 if (samdb_msg_add_delete(secret_state->sam_ldb,
2497 mem_ctx, msg, "currentValue")) {
2498 return NT_STATUS_NO_MEMORY;
2500 if (samdb_msg_add_delete(secret_state->sam_ldb,
2501 mem_ctx, msg, "lastSetTime")) {
2502 return NT_STATUS_NO_MEMORY;
2508 if (r->in.new_val) {
2510 crypt_secret.data = r->in.new_val->data;
2511 crypt_secret.length = r->in.new_val->size;
2513 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2514 if (!NT_STATUS_IS_OK(status)) {
2518 val.data = secret.data;
2519 val.length = secret.length;
2522 if (samdb_msg_add_value(secret_state->sam_ldb,
2523 mem_ctx, msg, "currentValue", &val) != 0) {
2524 return NT_STATUS_NO_MEMORY;
2527 /* set new value mtime */
2528 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2529 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2530 return NT_STATUS_NO_MEMORY;
2533 /* If the old value is not set, then migrate the
2534 * current value to the old value */
2535 if (!r->in.old_val) {
2536 const struct ldb_val *new_val;
2537 NTTIME last_set_time;
2538 struct ldb_message **res;
2539 const char *attrs[] = {
2545 /* search for the secret record */
2546 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
2547 secret_state->secret_dn, &res, attrs);
2549 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2553 DEBUG(0,("Found %d records matching dn=%s\n", ret,
2554 ldb_dn_get_linearized(secret_state->secret_dn)));
2555 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2558 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2559 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2563 if (samdb_msg_add_value(secret_state->sam_ldb,
2564 mem_ctx, msg, "priorValue",
2566 return NT_STATUS_NO_MEMORY;
2570 /* set new value mtime */
2571 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2572 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2573 mem_ctx, msg, "priorSetTime", last_set_time) != 0) {
2574 return NT_STATUS_NO_MEMORY;
2580 /* modify the samdb record */
2581 ret = samdb_replace(secret_state->sam_ldb, mem_ctx, msg);
2583 /* we really need samdb.c to return NTSTATUS */
2584 return NT_STATUS_UNSUCCESSFUL;
2587 return NT_STATUS_OK;
2594 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2595 struct lsa_QuerySecret *r)
2597 struct dcesrv_handle *h;
2598 struct lsa_secret_state *secret_state;
2599 struct ldb_message *msg;
2600 DATA_BLOB session_key;
2601 DATA_BLOB crypt_secret, secret;
2603 struct ldb_message **res;
2604 const char *attrs[] = {
2614 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2616 secret_state = h->data;
2618 /* pull all the user attributes */
2619 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2620 secret_state->secret_dn, &res, attrs);
2622 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2626 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2627 if (!NT_STATUS_IS_OK(nt_status)) {
2631 if (r->in.old_val) {
2632 const struct ldb_val *prior_val;
2633 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2634 if (!r->out.old_val) {
2635 return NT_STATUS_NO_MEMORY;
2637 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
2639 if (prior_val && prior_val->length) {
2640 secret.data = prior_val->data;
2641 secret.length = prior_val->length;
2644 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2645 if (!crypt_secret.length) {
2646 return NT_STATUS_NO_MEMORY;
2648 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2649 if (!r->out.old_val->buf) {
2650 return NT_STATUS_NO_MEMORY;
2652 r->out.old_val->buf->size = crypt_secret.length;
2653 r->out.old_val->buf->length = crypt_secret.length;
2654 r->out.old_val->buf->data = crypt_secret.data;
2658 if (r->in.old_mtime) {
2659 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2660 if (!r->out.old_mtime) {
2661 return NT_STATUS_NO_MEMORY;
2663 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
2666 if (r->in.new_val) {
2667 const struct ldb_val *new_val;
2668 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2669 if (!r->out.new_val) {
2670 return NT_STATUS_NO_MEMORY;
2673 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2675 if (new_val && new_val->length) {
2676 secret.data = new_val->data;
2677 secret.length = new_val->length;
2680 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2681 if (!crypt_secret.length) {
2682 return NT_STATUS_NO_MEMORY;
2684 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2685 if (!r->out.new_val->buf) {
2686 return NT_STATUS_NO_MEMORY;
2688 r->out.new_val->buf->length = crypt_secret.length;
2689 r->out.new_val->buf->size = crypt_secret.length;
2690 r->out.new_val->buf->data = crypt_secret.data;
2694 if (r->in.new_mtime) {
2695 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2696 if (!r->out.new_mtime) {
2697 return NT_STATUS_NO_MEMORY;
2699 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2702 return NT_STATUS_OK;
2709 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
2710 TALLOC_CTX *mem_ctx,
2711 struct lsa_LookupPrivValue *r)
2713 struct dcesrv_handle *h;
2714 struct lsa_policy_state *state;
2717 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2721 id = sec_privilege_id(r->in.name->string);
2723 return NT_STATUS_NO_SUCH_PRIVILEGE;
2726 r->out.luid->low = id;
2727 r->out.luid->high = 0;
2729 return NT_STATUS_OK;
2736 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
2737 TALLOC_CTX *mem_ctx,
2738 struct lsa_LookupPrivName *r)
2740 struct dcesrv_handle *h;
2741 struct lsa_policy_state *state;
2742 const char *privname;
2744 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2748 if (r->in.luid->high != 0) {
2749 return NT_STATUS_NO_SUCH_PRIVILEGE;
2752 privname = sec_privilege_name(r->in.luid->low);
2753 if (privname == NULL) {
2754 return NT_STATUS_NO_SUCH_PRIVILEGE;
2757 r->out.name = talloc(mem_ctx, struct lsa_StringLarge);
2758 if (r->out.name == NULL) {
2759 return NT_STATUS_NO_MEMORY;
2761 r->out.name->string = privname;
2763 return NT_STATUS_OK;
2768 lsa_LookupPrivDisplayName
2770 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
2771 TALLOC_CTX *mem_ctx,
2772 struct lsa_LookupPrivDisplayName *r)
2774 struct dcesrv_handle *h;
2775 struct lsa_policy_state *state;
2778 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2782 id = sec_privilege_id(r->in.name->string);
2784 return NT_STATUS_NO_SUCH_PRIVILEGE;
2787 r->out.disp_name = talloc(mem_ctx, struct lsa_StringLarge);
2788 if (r->out.disp_name == NULL) {
2789 return NT_STATUS_NO_MEMORY;
2792 r->out.disp_name->string = sec_privilege_display_name(id, r->in.language_id);
2793 if (r->out.disp_name->string == NULL) {
2794 return NT_STATUS_INTERNAL_ERROR;
2797 return NT_STATUS_OK;
2804 static NTSTATUS dcesrv_lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2805 struct lsa_DeleteObject *r)
2807 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2812 lsa_EnumAccountsWithUserRight
2814 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
2815 TALLOC_CTX *mem_ctx,
2816 struct lsa_EnumAccountsWithUserRight *r)
2818 struct dcesrv_handle *h;
2819 struct lsa_policy_state *state;
2821 struct ldb_message **res;
2822 const char * const attrs[] = { "objectSid", NULL};
2823 const char *privname;
2825 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2829 if (r->in.name == NULL) {
2830 return NT_STATUS_NO_SUCH_PRIVILEGE;
2833 privname = r->in.name->string;
2834 if (sec_privilege_id(privname) == -1) {
2835 return NT_STATUS_NO_SUCH_PRIVILEGE;
2838 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
2839 "privilege=%s", privname);
2841 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2844 return NT_STATUS_NO_MORE_ENTRIES;
2847 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2848 if (r->out.sids->sids == NULL) {
2849 return NT_STATUS_NO_MEMORY;
2851 for (i=0;i<ret;i++) {
2852 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2853 res[i], "objectSid");
2854 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2856 r->out.sids->num_sids = ret;
2858 return NT_STATUS_OK;
2863 lsa_AddAccountRights
2865 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
2866 TALLOC_CTX *mem_ctx,
2867 struct lsa_AddAccountRights *r)
2869 struct dcesrv_handle *h;
2870 struct lsa_policy_state *state;
2872 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2876 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2878 r->in.sid, r->in.rights);
2883 lsa_RemoveAccountRights
2885 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
2886 TALLOC_CTX *mem_ctx,
2887 struct lsa_RemoveAccountRights *r)
2889 struct dcesrv_handle *h;
2890 struct lsa_policy_state *state;
2892 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2896 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2897 LDB_FLAG_MOD_DELETE,
2898 r->in.sid, r->in.rights);
2903 lsa_StorePrivateData
2905 static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2906 struct lsa_StorePrivateData *r)
2908 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2913 lsa_RetrievePrivateData
2915 static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2916 struct lsa_RetrievePrivateData *r)
2918 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2925 static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2926 struct lsa_GetUserName *r)
2928 NTSTATUS status = NT_STATUS_OK;
2929 const char *account_name;
2930 const char *authority_name;
2931 struct lsa_String *_account_name;
2932 struct lsa_StringPointer *_authority_name = NULL;
2934 /* this is what w2k3 does */
2935 r->out.account_name = r->in.account_name;
2936 r->out.authority_name = r->in.authority_name;
2938 if (r->in.account_name && r->in.account_name->string) {
2939 return NT_STATUS_INVALID_PARAMETER;
2942 if (r->in.authority_name &&
2943 r->in.authority_name->string &&
2944 r->in.authority_name->string->string) {
2945 return NT_STATUS_INVALID_PARAMETER;
2948 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
2949 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
2951 _account_name = talloc(mem_ctx, struct lsa_String);
2952 NT_STATUS_HAVE_NO_MEMORY(_account_name);
2953 _account_name->string = account_name;
2955 if (r->in.authority_name) {
2956 _authority_name = talloc(mem_ctx, struct lsa_StringPointer);
2957 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
2958 _authority_name->string = talloc(mem_ctx, struct lsa_String);
2959 NT_STATUS_HAVE_NO_MEMORY(_authority_name->string);
2960 _authority_name->string->string = authority_name;
2963 r->out.account_name = _account_name;
2964 r->out.authority_name = _authority_name;
2972 static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
2973 TALLOC_CTX *mem_ctx,
2974 struct lsa_SetInfoPolicy2 *r)
2976 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2980 lsa_QueryDomainInformationPolicy
2982 static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2983 TALLOC_CTX *mem_ctx,
2984 struct lsa_QueryDomainInformationPolicy *r)
2986 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2990 lsa_SetDomInfoPolicy
2992 static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2993 TALLOC_CTX *mem_ctx,
2994 struct lsa_SetDomainInformationPolicy *r)
2996 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3002 static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
3003 TALLOC_CTX *mem_ctx,
3004 struct lsa_TestCall *r)
3006 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3010 lookup a SID for 1 name
3012 static NTSTATUS dcesrv_lsa_lookup_name(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
3013 const char *name, struct dom_sid **sid, uint32_t *atype)
3016 struct ldb_message **res;
3017 const char * const attrs[] = { "objectSid", "sAMAccountType", NULL};
3020 p = strchr_m(name, '\\');
3022 /* TODO: properly parse the domain prefix here, and use it to
3027 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs, "sAMAccountName=%s", ldb_binary_encode_string(mem_ctx, name));
3029 *sid = samdb_result_dom_sid(mem_ctx, res[0], "objectSid");
3031 return NT_STATUS_INVALID_SID;
3034 *atype = samdb_result_uint(res[0], "sAMAccountType", 0);
3036 return NT_STATUS_OK;
3039 /* need to add a call into sidmap to check for a allocated sid */
3041 return NT_STATUS_INVALID_SID;
3048 static NTSTATUS dcesrv_lsa_LookupNames3(struct dcesrv_call_state *dce_call,
3049 TALLOC_CTX *mem_ctx,
3050 struct lsa_LookupNames3 *r)
3052 struct lsa_policy_state *policy_state;
3053 struct dcesrv_handle *policy_handle;
3055 NTSTATUS status = NT_STATUS_OK;
3057 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
3059 policy_state = policy_handle->data;
3061 r->out.domains = NULL;
3063 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
3064 if (r->out.domains == NULL) {
3065 return NT_STATUS_NO_MEMORY;
3068 r->out.sids = talloc_zero(mem_ctx, struct lsa_TransSidArray3);
3069 if (r->out.sids == NULL) {
3070 return NT_STATUS_NO_MEMORY;
3075 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid3,
3077 if (r->out.sids->sids == NULL) {
3078 return NT_STATUS_NO_MEMORY;
3081 for (i=0;i<r->in.num_names;i++) {
3082 const char *name = r->in.names[i].string;
3083 struct dom_sid *sid;
3084 uint32_t atype, rtype, sid_index;
3087 r->out.sids->count++;
3090 r->out.sids->sids[i].sid_type = SID_NAME_UNKNOWN;
3091 r->out.sids->sids[i].sid = NULL;
3092 r->out.sids->sids[i].sid_index = 0xFFFFFFFF;
3093 r->out.sids->sids[i].unknown = 0;
3095 status2 = dcesrv_lsa_lookup_name(policy_state, mem_ctx, name, &sid, &atype);
3096 if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
3097 status = STATUS_SOME_UNMAPPED;
3101 rtype = samdb_atype_map(atype);
3102 if (rtype == SID_NAME_UNKNOWN) {
3103 status = STATUS_SOME_UNMAPPED;
3107 status2 = dcesrv_lsa_authority_list(policy_state, mem_ctx, sid, r->out.domains, &sid_index);
3108 if (!NT_STATUS_IS_OK(status2)) {
3112 r->out.sids->sids[i].sid_type = rtype;
3113 r->out.sids->sids[i].sid = sid;
3114 r->out.sids->sids[i].sid_index = sid_index;
3115 r->out.sids->sids[i].unknown = 0;
3124 Identical to LookupNames3, but doesn't take a policy handle
3127 static NTSTATUS dcesrv_lsa_LookupNames4(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3128 struct lsa_LookupNames4 *r)
3130 struct lsa_LookupNames3 r2;
3131 struct lsa_OpenPolicy2 pol;
3133 struct dcesrv_handle *h;
3135 /* No policy handle on the wire, so make one up here */
3136 r2.in.handle = talloc(mem_ctx, struct policy_handle);
3137 if (!r2.in.handle) {
3138 return NT_STATUS_NO_MEMORY;
3141 pol.out.handle = r2.in.handle;
3142 pol.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3144 pol.in.system_name = NULL;
3145 status = dcesrv_lsa_OpenPolicy2(dce_call, mem_ctx, &pol);
3146 if (!NT_STATUS_IS_OK(status)) {
3150 /* ensure this handle goes away at the end of this call */
3151 DCESRV_PULL_HANDLE(h, r2.in.handle, LSA_HANDLE_POLICY);
3152 talloc_steal(mem_ctx, h);
3154 r2.in.num_names = r->in.num_names;
3155 r2.in.names = r->in.names;
3156 r2.in.sids = r->in.sids;
3157 r2.in.count = r->in.count;
3158 r2.in.unknown1 = r->in.unknown1;
3159 r2.in.unknown2 = r->in.unknown2;
3160 r2.out.domains = r->out.domains;
3161 r2.out.sids = r->out.sids;
3162 r2.out.count = r->out.count;
3164 status = dcesrv_lsa_LookupNames3(dce_call, mem_ctx, &r2);
3165 if (dce_call->fault_code != 0) {
3169 r->out.domains = r2.out.domains;
3170 r->out.sids = r2.out.sids;
3171 r->out.count = r2.out.count;
3178 static NTSTATUS dcesrv_lsa_LookupNames2(struct dcesrv_call_state *dce_call,
3179 TALLOC_CTX *mem_ctx,
3180 struct lsa_LookupNames2 *r)
3182 struct lsa_policy_state *state;
3183 struct dcesrv_handle *h;
3185 NTSTATUS status = NT_STATUS_OK;
3187 r->out.domains = NULL;
3189 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3193 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
3194 if (r->out.domains == NULL) {
3195 return NT_STATUS_NO_MEMORY;
3198 r->out.sids = talloc_zero(mem_ctx, struct lsa_TransSidArray2);
3199 if (r->out.sids == NULL) {
3200 return NT_STATUS_NO_MEMORY;
3205 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid2,
3207 if (r->out.sids->sids == NULL) {
3208 return NT_STATUS_NO_MEMORY;
3211 for (i=0;i<r->in.num_names;i++) {
3212 const char *name = r->in.names[i].string;
3213 struct dom_sid *sid;
3214 uint32_t atype, rtype, sid_index;
3217 r->out.sids->count++;
3220 r->out.sids->sids[i].sid_type = SID_NAME_UNKNOWN;
3221 r->out.sids->sids[i].rid = 0xFFFFFFFF;
3222 r->out.sids->sids[i].sid_index = 0xFFFFFFFF;
3223 r->out.sids->sids[i].unknown = 0;
3225 status2 = dcesrv_lsa_lookup_name(state, mem_ctx, name, &sid, &atype);
3226 if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
3227 status = STATUS_SOME_UNMAPPED;
3231 rtype = samdb_atype_map(atype);
3232 if (rtype == SID_NAME_UNKNOWN) {
3233 status = STATUS_SOME_UNMAPPED;
3237 status2 = dcesrv_lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
3238 if (!NT_STATUS_IS_OK(status2)) {
3242 r->out.sids->sids[i].sid_type = rtype;
3243 r->out.sids->sids[i].rid = sid->sub_auths[sid->num_auths-1];
3244 r->out.sids->sids[i].sid_index = sid_index;
3245 r->out.sids->sids[i].unknown = 0;
3254 static NTSTATUS dcesrv_lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3255 struct lsa_LookupNames *r)
3257 struct lsa_LookupNames2 r2;
3261 r2.in.handle = r->in.handle;
3262 r2.in.num_names = r->in.num_names;
3263 r2.in.names = r->in.names;
3265 r2.in.level = r->in.level;
3266 r2.in.count = r->in.count;
3269 r2.out.count = r->out.count;
3271 status = dcesrv_lsa_LookupNames2(dce_call, mem_ctx, &r2);
3272 if (dce_call->fault_code != 0) {
3276 r->out.domains = r2.out.domains;
3277 r->out.sids = talloc(mem_ctx, struct lsa_TransSidArray);
3278 if (r->out.sids == NULL) {
3279 return NT_STATUS_NO_MEMORY;
3281 r->out.sids->count = r2.out.sids->count;
3282 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid,
3283 r->out.sids->count);
3284 if (r->out.sids->sids == NULL) {
3285 return NT_STATUS_NO_MEMORY;
3287 for (i=0;i<r->out.sids->count;i++) {
3288 r->out.sids->sids[i].sid_type = r2.out.sids->sids[i].sid_type;
3289 r->out.sids->sids[i].rid = r2.out.sids->sids[i].rid;
3290 r->out.sids->sids[i].sid_index = r2.out.sids->sids[i].sid_index;
3299 static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3300 struct lsa_CREDRWRITE *r)
3302 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3309 static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3310 struct lsa_CREDRREAD *r)
3312 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3319 static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3320 struct lsa_CREDRENUMERATE *r)
3322 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3327 lsa_CREDRWRITEDOMAINCREDENTIALS
3329 static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3330 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3332 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3337 lsa_CREDRREADDOMAINCREDENTIALS
3339 static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3340 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3342 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3349 static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3350 struct lsa_CREDRDELETE *r)
3352 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3357 lsa_CREDRGETTARGETINFO
3359 static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3360 struct lsa_CREDRGETTARGETINFO *r)
3362 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3367 lsa_CREDRPROFILELOADED
3369 static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3370 struct lsa_CREDRPROFILELOADED *r)
3372 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3377 lsa_CREDRGETSESSIONTYPES
3379 static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3380 struct lsa_CREDRGETSESSIONTYPES *r)
3382 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3387 lsa_LSARREGISTERAUDITEVENT
3389 static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3390 struct lsa_LSARREGISTERAUDITEVENT *r)
3392 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3397 lsa_LSARGENAUDITEVENT
3399 static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3400 struct lsa_LSARGENAUDITEVENT *r)
3402 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3407 lsa_LSARUNREGISTERAUDITEVENT
3409 static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3410 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3412 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3417 lsa_lsaRQueryForestTrustInformation
3419 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3420 struct lsa_lsaRQueryForestTrustInformation *r)
3422 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3427 lsa_LSARSETFORESTTRUSTINFORMATION
3429 static NTSTATUS dcesrv_lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3430 struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
3432 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3439 static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3440 struct lsa_CREDRRENAME *r)
3442 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3448 lsa_LSAROPENPOLICYSCE
3450 static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3451 struct lsa_LSAROPENPOLICYSCE *r)
3453 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3458 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
3460 static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3461 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
3463 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3468 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
3470 static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3471 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
3473 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3478 lsa_LSARADTREPORTSECURITYEVENT
3480 static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3481 struct lsa_LSARADTREPORTSECURITYEVENT *r)
3483 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3487 /* include the generated boilerplate */
3488 #include "librpc/gen_ndr/ndr_lsa_s.c"
3492 /*****************************************
3493 NOTE! The remaining calls below were
3494 removed in w2k3, so the DCESRV_FAULT()
3495 replies are the correct implementation. Do
3496 not try and fill these in with anything else
3497 ******************************************/
3500 dssetup_DsRoleDnsNameToFlatName
3502 static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3503 struct dssetup_DsRoleDnsNameToFlatName *r)
3505 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3510 dssetup_DsRoleDcAsDc
3512 static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3513 struct dssetup_DsRoleDcAsDc *r)
3515 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3520 dssetup_DsRoleDcAsReplica
3522 static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3523 struct dssetup_DsRoleDcAsReplica *r)
3525 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3530 dssetup_DsRoleDemoteDc
3532 static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3533 struct dssetup_DsRoleDemoteDc *r)
3535 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3540 dssetup_DsRoleGetDcOperationProgress
3542 static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3543 struct dssetup_DsRoleGetDcOperationProgress *r)
3545 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3550 dssetup_DsRoleGetDcOperationResults
3552 static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3553 struct dssetup_DsRoleGetDcOperationResults *r)
3555 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3560 dssetup_DsRoleCancel
3562 static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3563 struct dssetup_DsRoleCancel *r)
3565 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3570 dssetup_DsRoleServerSaveStateForUpgrade
3572 static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3573 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
3575 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3580 dssetup_DsRoleUpgradeDownlevelServer
3582 static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3583 struct dssetup_DsRoleUpgradeDownlevelServer *r)
3585 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3590 dssetup_DsRoleAbortDownlevelServerUpgrade
3592 static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3593 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
3595 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3599 /* include the generated boilerplate */
3600 #include "librpc/gen_ndr/ndr_dssetup_s.c"
3602 NTSTATUS dcerpc_server_lsa_init(void)
3606 ret = dcerpc_server_dssetup_init();
3607 if (!NT_STATUS_IS_OK(ret)) {
3610 ret = dcerpc_server_lsarpc_init();
3611 if (!NT_STATUS_IS_OK(ret)) {