r18364: Get us closer to schema compliance. The corrent names for "secret"
[Samba/ekacnet.git] / source4 / rpc_server / lsa / dcesrv_lsa.c
blob7fb62e2e0def040adb0f3778144d08004135b0b7
1 /*
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.
24 #include "includes.h"
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 "passdb/secrets.h"
34 #include "db_wrap.h"
35 #include "librpc/gen_ndr/ndr_dssetup.h"
38 this type allows us to distinguish handle types
40 enum lsa_handle {
41 LSA_HANDLE_POLICY,
42 LSA_HANDLE_ACCOUNT,
43 LSA_HANDLE_SECRET,
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;
54 uint32_t access_mask;
55 const struct ldb_dn *domain_dn;
56 const struct ldb_dn *builtin_dn;
57 const 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;
63 int mixed_domain;
68 state associated with a lsa_OpenAccount() operation
70 struct lsa_account_state {
71 struct lsa_policy_state *policy;
72 uint32_t access_mask;
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;
82 uint32_t access_mask;
83 struct ldb_dn *secret_dn;
84 struct ldb_context *sam_ldb;
85 BOOL global;
89 state associated with a lsa_OpenTrustedDomain() operation
91 struct lsa_trusted_domain_state {
92 struct lsa_policy_state *policy;
93 uint32_t access_mask;
94 const struct ldb_dn *trusted_domain_dn;
97 static NTSTATUS lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
98 TALLOC_CTX *mem_ctx,
99 struct lsa_EnumAccountRights *r);
101 static NTSTATUS lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
102 TALLOC_CTX *mem_ctx,
103 struct lsa_policy_state *state,
104 int ldb_flag,
105 struct dom_sid *sid,
106 const struct lsa_RightSet *rights);
109 lsa_Close
111 static NTSTATUS lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
112 struct lsa_Close *r)
114 struct dcesrv_handle *h;
116 *r->out.handle = *r->in.handle;
118 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
120 talloc_free(h);
122 ZERO_STRUCTP(r->out.handle);
124 return NT_STATUS_OK;
129 lsa_Delete
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;
135 int ret;
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);
141 talloc_free(h);
142 if (ret != 0) {
143 return NT_STATUS_INVALID_HANDLE;
146 return NT_STATUS_OK;
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);
151 talloc_free(h);
152 if (ret != 0) {
153 return NT_STATUS_INVALID_HANDLE;
156 return NT_STATUS_OK;
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;
161 NTSTATUS status;
163 rights = talloc(mem_ctx, struct lsa_RightSet);
165 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
167 astate = h->data;
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)) {
175 return NT_STATUS_OK;
178 if (!NT_STATUS_IS_OK(status)) {
179 return status;
182 status = lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
183 LDB_FLAG_MOD_DELETE, astate->account_sid,
184 r2.out.rights);
185 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
186 return NT_STATUS_OK;
189 if (!NT_STATUS_IS_OK(status)) {
190 return status;
194 return NT_STATUS_INVALID_HANDLE;
199 lsa_EnumPrivs
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;
206 int i;
207 const char *privname;
209 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
211 state = h->data;
213 i = *r->in.resume_handle;
214 if (i == 0) i = 1;
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,
221 r->out.privs->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];
228 e->luid.low = i;
229 e->luid.high = 0;
230 e->name.string = privname;
231 r->out.privs->count++;
232 i++;
235 *r->out.resume_handle = i;
237 return NT_STATUS_OK;
242 lsa_QuerySecObj
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);
252 lsa_SetSecObj
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);
262 lsa_ChangePassword
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 const struct ldb_dn *partitions_basedn;
275 struct ldb_result *dom_res;
276 const char *dom_attrs[] = {
277 "objectSid",
278 "objectGUID",
279 "nTMixedDomain",
280 NULL
282 struct ldb_result *ref_res;
283 const char *ref_attrs[] = {
284 "nETBIOSName",
285 "dnsRoot",
286 NULL
288 char *ref_filter;
289 int ret;
291 state = talloc(mem_ctx, struct lsa_policy_state);
292 if (!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
310 fetching here */
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_linearize(mem_ctx, state->domain_dn));
342 if (!ref_filter) {
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
372 fetching here */
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
379 fetching here */
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;
391 *_state = state;
393 return NT_STATUS_OK;
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,
403 TALLOC_CTX *mem_ctx,
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;
415 uint32_t flags = 0;
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;
432 break;
433 case ROLE_DOMAIN_MEMBER:
434 role = DS_ROLE_MEMBER_SERVER;
435 break;
436 case ROLE_DOMAIN_BDC:
437 role = DS_ROLE_BACKUP_DC;
438 break;
439 case ROLE_DOMAIN_PDC:
440 role = DS_ROLE_PRIMARY_DC;
441 break;
444 switch (lp_server_role()) {
445 case ROLE_STANDALONE:
446 domain = talloc_strdup(mem_ctx, lp_workgroup());
447 W_ERROR_HAVE_NO_MEMORY(domain);
448 break;
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? */
453 break;
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;
468 break;
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;
478 r->out.info = info;
479 return WERR_OK;
481 case DS_ROLE_UPGRADE_STATUS:
483 info->upgrade.upgrading = DS_ROLE_NOT_UPGRADING;
484 info->upgrade.previous_role = DS_ROLE_PREVIOUS_UNKNOWN;
486 r->out.info = info;
487 return WERR_OK;
489 case DS_ROLE_OP_STATUS:
491 info->opstatus.status = DS_ROLE_OP_IDLE;
493 r->out.info = info;
494 return WERR_OK;
496 default:
497 return WERR_INVALID_PARAM;
500 return WERR_INVALID_PARAM;
504 lsa_OpenPolicy2
506 static NTSTATUS lsa_OpenPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
507 struct lsa_OpenPolicy2 *r)
509 NTSTATUS status;
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)) {
517 return status;
520 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_POLICY);
521 if (!handle) {
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
533 does */
535 return NT_STATUS_OK;
539 lsa_OpenPolicy
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;
567 return NT_STATUS_OK;
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;
582 return NT_STATUS_OK;
586 lsa_QueryInfoPolicy2
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;
594 r->out.info = NULL;
596 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
598 state = h->data;
600 r->out.info = talloc(mem_ctx, union lsa_PolicyInformation);
601 if (!r->out.info) {
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;
620 lsa_QueryInfoPolicy
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;
626 NTSTATUS status;
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;
635 return status;
639 lsa_SetInfoPolicy
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);
649 lsa_ClearAuditLog
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);
659 lsa_CreateAccount
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);
673 state = h->data;
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) {
682 talloc_free(astate);
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);
690 if (!ah) {
691 talloc_free(astate);
692 return NT_STATUS_NO_MEMORY;
695 ah->data = talloc_steal(ah, astate);
697 *r->out.acct_handle = ah->wire_handle;
699 return NT_STATUS_OK;
704 lsa_EnumAccounts
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;
711 int ret, i;
712 struct ldb_message **res;
713 const char * const attrs[] = { "objectSid", NULL};
714 uint32_t count;
716 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
718 state = h->data;
720 /* NOTE: This call must only return accounts that have at least
721 one privilege set
723 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
724 "(&(objectSid=*)(privilege=*))");
725 if (ret < 0) {
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;
738 if (count == 0) {
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],
751 "objectSid");
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;
758 return NT_STATUS_OK;
764 lsa_CreateTrustedDomainEx2
766 static NTSTATUS lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
767 TALLOC_CTX *mem_ctx,
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,
777 TALLOC_CTX *mem_ctx,
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[] = {
795 NULL
797 const char *name;
798 int ret;
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);
817 if (msg == NULL) {
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));
826 if (ret > 0) {
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_linearize(mem_ctx, policy_state->system_dn)));
833 return NT_STATUS_INTERNAL_DB_CORRUPTION;
836 msg->dn = ldb_dn_build_child(mem_ctx, "cn",
837 r->in.info->name.string,
838 policy_state->system_dn);
839 if (!msg->dn) {
840 return NT_STATUS_NO_MEMORY;
843 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "cn", name);
844 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "flatname", name);
846 if (r->in.info->sid) {
847 const char *sid_string = dom_sid_string(mem_ctx, r->in.info->sid);
848 if (!sid_string) {
849 return NT_STATUS_NO_MEMORY;
852 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "securityIdentifier", sid_string);
855 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "objectClass", "trustedDomain");
857 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
859 /* create the trusted_domain */
860 ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg);
861 if (ret != LDB_SUCCESS) {
862 DEBUG(0,("Failed to create trusted_domain record %s: %s\n",
863 ldb_dn_linearize(mem_ctx, msg->dn), ldb_errstring(trusted_domain_state->policy->sam_ldb)));
864 return NT_STATUS_INTERNAL_DB_CORRUPTION;
867 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
868 if (!handle) {
869 return NT_STATUS_NO_MEMORY;
872 handle->data = talloc_steal(handle, trusted_domain_state);
874 trusted_domain_state->access_mask = r->in.access_mask;
875 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
877 *r->out.trustdom_handle = handle->wire_handle;
879 return NT_STATUS_OK;
883 lsa_OpenTrustedDomain
885 static NTSTATUS lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
886 struct lsa_OpenTrustedDomain *r)
888 struct dcesrv_handle *policy_handle;
890 struct lsa_policy_state *policy_state;
891 struct lsa_trusted_domain_state *trusted_domain_state;
892 struct dcesrv_handle *handle;
893 struct ldb_message **msgs;
894 const char *attrs[] = {
895 NULL
898 const char *sid_string;
899 int ret;
901 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
902 ZERO_STRUCTP(r->out.trustdom_handle);
903 policy_state = policy_handle->data;
905 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
906 if (!trusted_domain_state) {
907 return NT_STATUS_NO_MEMORY;
909 trusted_domain_state->policy = policy_state;
911 sid_string = dom_sid_string(mem_ctx, r->in.sid);
912 if (!sid_string) {
913 return NT_STATUS_NO_MEMORY;
916 /* search for the trusted_domain record */
917 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
918 mem_ctx, policy_state->system_dn, &msgs, attrs,
919 "(&(securityIdentifier=%s)(objectclass=trustedDomain))",
920 sid_string);
921 if (ret == 0) {
922 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
925 if (ret != 1) {
926 DEBUG(0,("Found %d records matching DN %s\n", ret,
927 ldb_dn_linearize(mem_ctx, policy_state->system_dn)));
928 return NT_STATUS_INTERNAL_DB_CORRUPTION;
931 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
933 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
934 if (!handle) {
935 return NT_STATUS_NO_MEMORY;
938 handle->data = talloc_steal(handle, trusted_domain_state);
940 trusted_domain_state->access_mask = r->in.access_mask;
941 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
943 *r->out.trustdom_handle = handle->wire_handle;
945 return NT_STATUS_OK;
950 lsa_OpenTrustedDomainByName
952 static NTSTATUS lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
953 TALLOC_CTX *mem_ctx,
954 struct lsa_OpenTrustedDomainByName *r)
956 struct dcesrv_handle *policy_handle;
958 struct lsa_policy_state *policy_state;
959 struct lsa_trusted_domain_state *trusted_domain_state;
960 struct dcesrv_handle *handle;
961 struct ldb_message **msgs;
962 const char *attrs[] = {
963 NULL
966 int ret;
968 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
969 ZERO_STRUCTP(r->out.trustdom_handle);
970 policy_state = policy_handle->data;
972 if (!r->in.name.string) {
973 return NT_STATUS_INVALID_PARAMETER;
976 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
977 if (!trusted_domain_state) {
978 return NT_STATUS_NO_MEMORY;
980 trusted_domain_state->policy = policy_state;
982 /* search for the trusted_domain record */
983 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
984 mem_ctx, policy_state->system_dn, &msgs, attrs,
985 "(&(flatname=%s)(objectclass=trustedDomain))",
986 ldb_binary_encode_string(mem_ctx, r->in.name.string));
987 if (ret == 0) {
988 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
991 if (ret != 1) {
992 DEBUG(0,("Found %d records matching DN %s\n", ret,
993 ldb_dn_linearize(mem_ctx, policy_state->system_dn)));
994 return NT_STATUS_INTERNAL_DB_CORRUPTION;
997 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
999 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1000 if (!handle) {
1001 return NT_STATUS_NO_MEMORY;
1004 handle->data = talloc_steal(handle, trusted_domain_state);
1006 trusted_domain_state->access_mask = r->in.access_mask;
1007 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1009 *r->out.trustdom_handle = handle->wire_handle;
1011 return NT_STATUS_OK;
1017 lsa_SetTrustedDomainInfo
1019 static NTSTATUS lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1020 struct lsa_SetTrustedDomainInfo *r)
1022 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1028 lsa_SetInfomrationTrustedDomain
1030 static NTSTATUS lsa_SetInformationTrustedDomain(struct dcesrv_call_state *dce_call,
1031 TALLOC_CTX *mem_ctx,
1032 struct lsa_SetInformationTrustedDomain *r)
1034 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1039 lsa_DeleteTrustedDomain
1041 static NTSTATUS lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1042 struct lsa_DeleteTrustedDomain *r)
1044 NTSTATUS status;
1045 struct lsa_OpenTrustedDomain open;
1046 struct lsa_Delete delete;
1047 struct dcesrv_handle *h;
1049 open.in.handle = r->in.handle;
1050 open.in.sid = r->in.dom_sid;
1051 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1052 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1053 if (!open.out.trustdom_handle) {
1054 return NT_STATUS_NO_MEMORY;
1056 status = lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
1057 if (!NT_STATUS_IS_OK(status)) {
1058 return status;
1061 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1062 talloc_steal(mem_ctx, h);
1064 delete.in.handle = open.out.trustdom_handle;
1065 status = lsa_Delete(dce_call, mem_ctx, &delete);
1066 if (!NT_STATUS_IS_OK(status)) {
1067 return status;
1069 return NT_STATUS_OK;
1072 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx,
1073 struct ldb_message *msg,
1074 struct lsa_TrustDomainInfoInfoEx *info_ex)
1076 info_ex->domain_name.string
1077 = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
1078 info_ex->netbios_name.string
1079 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1080 info_ex->sid
1081 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1082 info_ex->trust_direction
1083 = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
1084 info_ex->trust_type
1085 = ldb_msg_find_attr_as_int(msg, "trustType", 0);
1086 info_ex->trust_attributes
1087 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);
1088 return NT_STATUS_OK;
1092 lsa_QueryTrustedDomainInfo
1094 static NTSTATUS lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1095 struct lsa_QueryTrustedDomainInfo *r)
1097 struct dcesrv_handle *h;
1098 struct lsa_trusted_domain_state *trusted_domain_state;
1099 struct ldb_message *msg;
1100 int ret;
1101 struct ldb_message **res;
1102 const char *attrs[] = {
1103 "flatname",
1104 "trustPartner",
1105 "securityIdentifier",
1106 "trustDirection",
1107 "trustType",
1108 "trustAttributes",
1109 NULL
1112 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
1114 trusted_domain_state = h->data;
1116 /* pull all the user attributes */
1117 ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
1118 trusted_domain_state->trusted_domain_dn, &res, attrs);
1119 if (ret != 1) {
1120 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1122 msg = res[0];
1124 r->out.info = talloc(mem_ctx, union lsa_TrustedDomainInfo);
1125 if (!r->out.info) {
1126 return NT_STATUS_NO_MEMORY;
1128 switch (r->in.level) {
1129 case LSA_TRUSTED_DOMAIN_INFO_NAME:
1130 r->out.info->name.netbios_name.string
1131 = samdb_result_string(msg, "flatname", NULL);
1132 break;
1133 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1134 r->out.info->posix_offset.posix_offset
1135 = samdb_result_uint(msg, "posixOffset", 0);
1136 break;
1137 #if 0 /* Win2k3 doesn't implement this */
1138 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
1139 r->out.info->info_basic.netbios_name.string
1140 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1141 r->out.info->info_basic.sid
1142 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1143 break;
1144 #endif
1145 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1146 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->info_ex);
1148 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1149 ZERO_STRUCT(r->out.info->full_info);
1150 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->full_info.info_ex);
1152 case LSA_TRUSTED_DOMAIN_INFO_INFO_ALL:
1153 ZERO_STRUCT(r->out.info->info_all);
1154 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->info_all.info_ex);
1156 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS_INFO:
1157 case LSA_TRUSTED_DOMAIN_INFO_11:
1158 /* oops, we don't want to return the info after all */
1159 talloc_free(r->out.info);
1160 r->out.info = NULL;
1161 return NT_STATUS_INVALID_PARAMETER;
1162 default:
1163 /* oops, we don't want to return the info after all */
1164 talloc_free(r->out.info);
1165 r->out.info = NULL;
1166 return NT_STATUS_INVALID_INFO_CLASS;
1169 return NT_STATUS_OK;
1174 lsa_QueryTrustedDomainInfoBySid
1176 static NTSTATUS lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1177 struct lsa_QueryTrustedDomainInfoBySid *r)
1179 NTSTATUS status;
1180 struct lsa_OpenTrustedDomain open;
1181 struct lsa_QueryTrustedDomainInfo query;
1182 struct dcesrv_handle *h;
1183 open.in.handle = r->in.handle;
1184 open.in.sid = r->in.dom_sid;
1185 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1186 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1187 if (!open.out.trustdom_handle) {
1188 return NT_STATUS_NO_MEMORY;
1190 status = lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
1191 if (!NT_STATUS_IS_OK(status)) {
1192 return status;
1195 /* Ensure this handle goes away at the end of this call */
1196 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1197 talloc_steal(mem_ctx, h);
1199 query.in.trustdom_handle = open.out.trustdom_handle;
1200 query.in.level = r->in.level;
1201 status = lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1202 if (!NT_STATUS_IS_OK(status)) {
1203 return status;
1206 r->out.info = query.out.info;
1207 return NT_STATUS_OK;
1211 lsa_SetTrustedDomainInfoByName
1213 static NTSTATUS lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1214 TALLOC_CTX *mem_ctx,
1215 struct lsa_SetTrustedDomainInfoByName *r)
1217 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1221 lsa_QueryTrustedDomainInfoByName
1223 static NTSTATUS lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1224 TALLOC_CTX *mem_ctx,
1225 struct lsa_QueryTrustedDomainInfoByName *r)
1227 NTSTATUS status;
1228 struct lsa_OpenTrustedDomainByName open;
1229 struct lsa_QueryTrustedDomainInfo query;
1230 struct dcesrv_handle *h;
1231 open.in.handle = r->in.handle;
1232 open.in.name = r->in.trusted_domain;
1233 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1234 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1235 if (!open.out.trustdom_handle) {
1236 return NT_STATUS_NO_MEMORY;
1238 status = lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &open);
1239 if (!NT_STATUS_IS_OK(status)) {
1240 return status;
1243 /* Ensure this handle goes away at the end of this call */
1244 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1245 talloc_steal(mem_ctx, h);
1247 query.in.trustdom_handle = open.out.trustdom_handle;
1248 query.in.level = r->in.level;
1249 status = lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1250 if (!NT_STATUS_IS_OK(status)) {
1251 return status;
1254 r->out.info = query.out.info;
1255 return NT_STATUS_OK;
1259 lsa_CloseTrustedDomainEx
1261 static NTSTATUS lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
1262 TALLOC_CTX *mem_ctx,
1263 struct lsa_CloseTrustedDomainEx *r)
1265 /* The result of a bad hair day from an IDL programmer? Not
1266 * implmented in Win2k3. You should always just lsa_Close
1267 * anyway. */
1268 return NT_STATUS_NOT_IMPLEMENTED;
1273 comparison function for sorting lsa_DomainInformation array
1275 static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
1277 return strcasecmp_m(e1->name.string, e2->name.string);
1281 lsa_EnumTrustDom
1283 static NTSTATUS lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1284 struct lsa_EnumTrustDom *r)
1286 struct dcesrv_handle *policy_handle;
1287 struct lsa_DomainInfo *entries;
1288 struct lsa_policy_state *policy_state;
1289 struct ldb_message **domains;
1290 const char *attrs[] = {
1291 "flatname",
1292 "securityIdentifier",
1293 NULL
1297 int count, i;
1299 *r->out.resume_handle = 0;
1301 r->out.domains->domains = NULL;
1302 r->out.domains->count = 0;
1304 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1306 policy_state = policy_handle->data;
1308 /* search for all users in this domain. This could possibly be cached and
1309 resumed based on resume_key */
1310 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1311 "objectclass=trustedDomain");
1312 if (count == -1) {
1313 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1315 if (count == 0 || r->in.max_size == 0) {
1316 return NT_STATUS_OK;
1319 /* convert to lsa_TrustInformation format */
1320 entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
1321 if (!entries) {
1322 return NT_STATUS_NO_MEMORY;
1324 for (i=0;i<count;i++) {
1325 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
1326 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
1329 /* sort the results by name */
1330 qsort(entries, count, sizeof(*entries),
1331 (comparison_fn_t)compare_DomainInfo);
1333 if (*r->in.resume_handle >= count) {
1334 *r->out.resume_handle = -1;
1336 return NT_STATUS_NO_MORE_ENTRIES;
1339 /* return the rest, limit by max_size. Note that we
1340 use the w2k3 element size value of 60 */
1341 r->out.domains->count = count - *r->in.resume_handle;
1342 r->out.domains->count = MIN(r->out.domains->count,
1343 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
1345 r->out.domains->domains = entries + *r->in.resume_handle;
1346 r->out.domains->count = r->out.domains->count;
1348 if (r->out.domains->count < count - *r->in.resume_handle) {
1349 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1350 return STATUS_MORE_ENTRIES;
1353 return NT_STATUS_OK;
1357 comparison function for sorting lsa_DomainInformation array
1359 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
1361 return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
1365 lsa_EnumTrustedDomainsEx
1367 static NTSTATUS lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1368 struct lsa_EnumTrustedDomainsEx *r)
1370 struct dcesrv_handle *policy_handle;
1371 struct lsa_TrustDomainInfoInfoEx *entries;
1372 struct lsa_policy_state *policy_state;
1373 struct ldb_message **domains;
1374 const char *attrs[] = {
1375 "flatname",
1376 "trustPartner",
1377 "securityIdentifier",
1378 "trustDirection",
1379 "trustType",
1380 "trustAttributes",
1381 NULL
1383 NTSTATUS nt_status;
1385 int count, i;
1387 *r->out.resume_handle = 0;
1389 r->out.domains->domains = NULL;
1390 r->out.domains->count = 0;
1392 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1394 policy_state = policy_handle->data;
1396 /* search for all users in this domain. This could possibly be cached and
1397 resumed based on resume_key */
1398 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1399 "objectclass=trustedDomain");
1400 if (count == -1) {
1401 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1403 if (count == 0 || r->in.max_size == 0) {
1404 return NT_STATUS_OK;
1407 /* convert to lsa_DomainInformation format */
1408 entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
1409 if (!entries) {
1410 return NT_STATUS_NO_MEMORY;
1412 for (i=0;i<count;i++) {
1413 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
1414 if (!NT_STATUS_IS_OK(nt_status)) {
1415 return nt_status;
1419 /* sort the results by name */
1420 qsort(entries, count, sizeof(*entries),
1421 (comparison_fn_t)compare_TrustDomainInfoInfoEx);
1423 if (*r->in.resume_handle >= count) {
1424 *r->out.resume_handle = -1;
1426 return NT_STATUS_NO_MORE_ENTRIES;
1429 /* return the rest, limit by max_size. Note that we
1430 use the w2k3 element size value of 60 */
1431 r->out.domains->count = count - *r->in.resume_handle;
1432 r->out.domains->count = MIN(r->out.domains->count,
1433 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
1435 r->out.domains->domains = entries + *r->in.resume_handle;
1436 r->out.domains->count = r->out.domains->count;
1438 if (r->out.domains->count < count - *r->in.resume_handle) {
1439 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1440 return STATUS_MORE_ENTRIES;
1443 return NT_STATUS_OK;
1448 return the authority name and authority sid, given a sid
1450 static NTSTATUS lsa_authority_name(struct lsa_policy_state *state,
1451 TALLOC_CTX *mem_ctx, struct dom_sid *sid,
1452 const char **authority_name,
1453 struct dom_sid **authority_sid)
1455 if (dom_sid_in_domain(state->domain_sid, sid)) {
1456 *authority_name = state->domain_name;
1457 *authority_sid = state->domain_sid;
1458 return NT_STATUS_OK;
1461 if (dom_sid_in_domain(state->builtin_sid, sid)) {
1462 *authority_name = "BUILTIN";
1463 *authority_sid = state->builtin_sid;
1464 return NT_STATUS_OK;
1467 *authority_sid = dom_sid_dup(mem_ctx, sid);
1468 if (*authority_sid == NULL) {
1469 return NT_STATUS_NO_MEMORY;
1471 (*authority_sid)->num_auths = 0;
1472 *authority_name = dom_sid_string(mem_ctx, *authority_sid);
1473 if (*authority_name == NULL) {
1474 return NT_STATUS_NO_MEMORY;
1477 return NT_STATUS_OK;
1481 add to the lsa_RefDomainList for LookupSids and LookupNames
1483 static NTSTATUS lsa_authority_list(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
1484 struct dom_sid *sid,
1485 struct lsa_RefDomainList *domains,
1486 uint32_t *sid_index)
1488 NTSTATUS status;
1489 const char *authority_name;
1490 struct dom_sid *authority_sid;
1491 int i;
1493 /* work out the authority name */
1494 status = lsa_authority_name(state, mem_ctx, sid,
1495 &authority_name, &authority_sid);
1496 if (!NT_STATUS_IS_OK(status)) {
1497 return status;
1500 /* see if we've already done this authority name */
1501 for (i=0;i<domains->count;i++) {
1502 if (strcmp(authority_name, domains->domains[i].name.string) == 0) {
1503 *sid_index = i;
1504 return NT_STATUS_OK;
1508 domains->domains = talloc_realloc(domains,
1509 domains->domains,
1510 struct lsa_DomainInfo,
1511 domains->count+1);
1512 if (domains->domains == NULL) {
1513 return NT_STATUS_NO_MEMORY;
1515 domains->domains[i].name.string = authority_name;
1516 domains->domains[i].sid = authority_sid;
1517 domains->count++;
1518 domains->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER * domains->count;
1519 *sid_index = i;
1521 return NT_STATUS_OK;
1525 lookup a name for 1 SID
1527 static NTSTATUS lsa_lookup_sid(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
1528 struct dom_sid *sid, const char *sid_str,
1529 const char **name, uint32_t *atype)
1531 int ret;
1532 struct ldb_message **res;
1533 const char * const attrs[] = { "sAMAccountName", "sAMAccountType", "name", NULL};
1534 NTSTATUS status;
1536 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
1537 "objectSid=%s", ldap_encode_ndr_dom_sid(mem_ctx, sid));
1538 if (ret == 1) {
1539 *name = ldb_msg_find_attr_as_string(res[0], "sAMAccountName", NULL);
1540 if (!*name) {
1541 *name = ldb_msg_find_attr_as_string(res[0], "name", NULL);
1542 if (!*name) {
1543 *name = talloc_strdup(mem_ctx, sid_str);
1544 NT_STATUS_HAVE_NO_MEMORY(*name);
1548 *atype = samdb_result_uint(res[0], "sAMAccountType", 0);
1550 return NT_STATUS_OK;
1553 status = sidmap_allocated_sid_lookup(state->sidmap, mem_ctx, sid, name, atype);
1555 return status;
1560 lsa_LookupSids2
1562 static NTSTATUS lsa_LookupSids2(struct dcesrv_call_state *dce_call,
1563 TALLOC_CTX *mem_ctx,
1564 struct lsa_LookupSids2 *r)
1566 struct lsa_policy_state *state;
1567 int i;
1568 NTSTATUS status = NT_STATUS_OK;
1570 r->out.domains = NULL;
1572 status = lsa_get_policy_state(dce_call, mem_ctx, &state);
1573 if (!NT_STATUS_IS_OK(status)) {
1574 return status;
1577 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
1578 if (r->out.domains == NULL) {
1579 return NT_STATUS_NO_MEMORY;
1582 r->out.names = talloc_zero(mem_ctx, struct lsa_TransNameArray2);
1583 if (r->out.names == NULL) {
1584 return NT_STATUS_NO_MEMORY;
1587 *r->out.count = 0;
1589 r->out.names->names = talloc_array(r->out.names, struct lsa_TranslatedName2,
1590 r->in.sids->num_sids);
1591 if (r->out.names->names == NULL) {
1592 return NT_STATUS_NO_MEMORY;
1595 for (i=0;i<r->in.sids->num_sids;i++) {
1596 struct dom_sid *sid = r->in.sids->sids[i].sid;
1597 char *sid_str = dom_sid_string(mem_ctx, sid);
1598 const char *name;
1599 uint32_t atype, rtype, sid_index;
1600 NTSTATUS status2;
1602 r->out.names->count++;
1603 (*r->out.count)++;
1605 r->out.names->names[i].sid_type = SID_NAME_UNKNOWN;
1606 r->out.names->names[i].name.string = sid_str;
1607 r->out.names->names[i].sid_index = 0xFFFFFFFF;
1608 r->out.names->names[i].unknown = 0;
1610 if (sid_str == NULL) {
1611 r->out.names->names[i].name.string = "(SIDERROR)";
1612 status = STATUS_SOME_UNMAPPED;
1613 continue;
1616 /* work out the authority name */
1617 status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
1618 if (!NT_STATUS_IS_OK(status2)) {
1619 return status2;
1622 status2 = lsa_lookup_sid(state, mem_ctx, sid, sid_str,
1623 &name, &atype);
1624 if (!NT_STATUS_IS_OK(status2)) {
1625 status = STATUS_SOME_UNMAPPED;
1626 continue;
1629 rtype = samdb_atype_map(atype);
1630 if (rtype == SID_NAME_UNKNOWN) {
1631 status = STATUS_SOME_UNMAPPED;
1632 continue;
1635 r->out.names->names[i].sid_type = rtype;
1636 r->out.names->names[i].name.string = name;
1637 r->out.names->names[i].sid_index = sid_index;
1638 r->out.names->names[i].unknown = 0;
1641 return status;
1646 lsa_LookupSids3
1648 Identical to LookupSids2, but doesn't take a policy handle
1651 static NTSTATUS lsa_LookupSids3(struct dcesrv_call_state *dce_call,
1652 TALLOC_CTX *mem_ctx,
1653 struct lsa_LookupSids3 *r)
1655 struct lsa_LookupSids2 r2;
1656 struct lsa_OpenPolicy2 pol;
1657 NTSTATUS status;
1658 struct dcesrv_handle *h;
1660 /* No policy handle on the wire, so make one up here */
1661 r2.in.handle = talloc(mem_ctx, struct policy_handle);
1662 if (!r2.in.handle) {
1663 return NT_STATUS_NO_MEMORY;
1666 pol.out.handle = r2.in.handle;
1667 pol.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1668 pol.in.attr = NULL;
1669 pol.in.system_name = NULL;
1670 status = lsa_OpenPolicy2(dce_call, mem_ctx, &pol);
1671 if (!NT_STATUS_IS_OK(status)) {
1672 return status;
1675 /* ensure this handle goes away at the end of this call */
1676 DCESRV_PULL_HANDLE(h, r2.in.handle, LSA_HANDLE_POLICY);
1677 talloc_steal(mem_ctx, h);
1679 r2.in.sids = r->in.sids;
1680 r2.in.names = r->in.names;
1681 r2.in.level = r->in.level;
1682 r2.in.count = r->in.count;
1683 r2.in.unknown1 = r->in.unknown1;
1684 r2.in.unknown2 = r->in.unknown2;
1685 r2.out.count = r->out.count;
1686 r2.out.names = r->out.names;
1688 status = lsa_LookupSids2(dce_call, mem_ctx, &r2);
1689 if (dce_call->fault_code != 0) {
1690 return status;
1693 r->out.domains = r2.out.domains;
1694 r->out.names = r2.out.names;
1695 r->out.count = r2.out.count;
1697 return status;
1702 lsa_LookupSids
1704 static NTSTATUS lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1705 struct lsa_LookupSids *r)
1707 struct lsa_LookupSids2 r2;
1708 NTSTATUS status;
1709 int i;
1711 r2.in.handle = r->in.handle;
1712 r2.in.sids = r->in.sids;
1713 r2.in.names = NULL;
1714 r2.in.level = r->in.level;
1715 r2.in.count = r->in.count;
1716 r2.in.unknown1 = 0;
1717 r2.in.unknown2 = 0;
1718 r2.out.count = r->out.count;
1719 r2.out.names = NULL;
1721 status = lsa_LookupSids2(dce_call, mem_ctx, &r2);
1722 if (dce_call->fault_code != 0) {
1723 return status;
1726 r->out.domains = r2.out.domains;
1727 if (!r2.out.names) {
1728 r->out.names = NULL;
1729 return status;
1732 r->out.names = talloc(mem_ctx, struct lsa_TransNameArray);
1733 if (r->out.names == NULL) {
1734 return NT_STATUS_NO_MEMORY;
1736 r->out.names->count = r2.out.names->count;
1737 r->out.names->names = talloc_array(r->out.names, struct lsa_TranslatedName,
1738 r->out.names->count);
1739 if (r->out.names->names == NULL) {
1740 return NT_STATUS_NO_MEMORY;
1742 for (i=0;i<r->out.names->count;i++) {
1743 r->out.names->names[i].sid_type = r2.out.names->names[i].sid_type;
1744 r->out.names->names[i].name.string = r2.out.names->names[i].name.string;
1745 r->out.names->names[i].sid_index = r2.out.names->names[i].sid_index;
1748 return status;
1753 lsa_OpenAccount
1755 static NTSTATUS lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1756 struct lsa_OpenAccount *r)
1758 struct dcesrv_handle *h, *ah;
1759 struct lsa_policy_state *state;
1760 struct lsa_account_state *astate;
1762 ZERO_STRUCTP(r->out.acct_handle);
1764 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1766 state = h->data;
1768 astate = talloc(dce_call->conn, struct lsa_account_state);
1769 if (astate == NULL) {
1770 return NT_STATUS_NO_MEMORY;
1773 astate->account_sid = dom_sid_dup(astate, r->in.sid);
1774 if (astate->account_sid == NULL) {
1775 talloc_free(astate);
1776 return NT_STATUS_NO_MEMORY;
1779 astate->policy = talloc_reference(astate, state);
1780 astate->access_mask = r->in.access_mask;
1782 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
1783 if (!ah) {
1784 talloc_free(astate);
1785 return NT_STATUS_NO_MEMORY;
1788 ah->data = talloc_steal(ah, astate);
1790 *r->out.acct_handle = ah->wire_handle;
1792 return NT_STATUS_OK;
1797 lsa_EnumPrivsAccount
1799 static NTSTATUS lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
1800 TALLOC_CTX *mem_ctx,
1801 struct lsa_EnumPrivsAccount *r)
1803 struct dcesrv_handle *h;
1804 struct lsa_account_state *astate;
1805 int ret, i;
1806 struct ldb_message **res;
1807 const char * const attrs[] = { "privilege", NULL};
1808 struct ldb_message_element *el;
1809 const char *sidstr;
1811 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1813 astate = h->data;
1815 r->out.privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
1816 r->out.privs->count = 0;
1817 r->out.privs->unknown = 0;
1818 r->out.privs->set = NULL;
1820 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
1821 if (sidstr == NULL) {
1822 return NT_STATUS_NO_MEMORY;
1825 ret = gendb_search(astate->policy->sam_ldb, mem_ctx, NULL, &res, attrs,
1826 "objectSid=%s", sidstr);
1827 if (ret != 1) {
1828 return NT_STATUS_OK;
1831 el = ldb_msg_find_element(res[0], "privilege");
1832 if (el == NULL || el->num_values == 0) {
1833 return NT_STATUS_OK;
1836 r->out.privs->set = talloc_array(r->out.privs,
1837 struct lsa_LUIDAttribute, el->num_values);
1838 if (r->out.privs->set == NULL) {
1839 return NT_STATUS_NO_MEMORY;
1842 for (i=0;i<el->num_values;i++) {
1843 int id = sec_privilege_id((const char *)el->values[i].data);
1844 if (id == -1) {
1845 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1847 r->out.privs->set[i].attribute = 0;
1848 r->out.privs->set[i].luid.low = id;
1849 r->out.privs->set[i].luid.high = 0;
1852 r->out.privs->count = el->num_values;
1854 return NT_STATUS_OK;
1858 lsa_EnumAccountRights
1860 static NTSTATUS lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
1861 TALLOC_CTX *mem_ctx,
1862 struct lsa_EnumAccountRights *r)
1864 struct dcesrv_handle *h;
1865 struct lsa_policy_state *state;
1866 int ret, i;
1867 struct ldb_message **res;
1868 const char * const attrs[] = { "privilege", NULL};
1869 const char *sidstr;
1870 struct ldb_message_element *el;
1872 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1874 state = h->data;
1876 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
1877 if (sidstr == NULL) {
1878 return NT_STATUS_NO_MEMORY;
1881 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
1882 "(&(objectSid=%s)(privilege=*))", sidstr);
1883 if (ret == 0) {
1884 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1886 if (ret > 1) {
1887 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1889 if (ret == -1) {
1890 DEBUG(3, ("searching for account rights for SID: %s failed: %s",
1891 dom_sid_string(mem_ctx, r->in.sid),
1892 ldb_errstring(state->sam_ldb)));
1893 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1896 el = ldb_msg_find_element(res[0], "privilege");
1897 if (el == NULL || el->num_values == 0) {
1898 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1901 r->out.rights->count = el->num_values;
1902 r->out.rights->names = talloc_array(r->out.rights,
1903 struct lsa_StringLarge, r->out.rights->count);
1904 if (r->out.rights->names == NULL) {
1905 return NT_STATUS_NO_MEMORY;
1908 for (i=0;i<el->num_values;i++) {
1909 r->out.rights->names[i].string = (const char *)el->values[i].data;
1912 return NT_STATUS_OK;
1918 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
1920 static NTSTATUS lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
1921 TALLOC_CTX *mem_ctx,
1922 struct lsa_policy_state *state,
1923 int ldb_flag,
1924 struct dom_sid *sid,
1925 const struct lsa_RightSet *rights)
1927 const char *sidstr;
1928 struct ldb_message *msg;
1929 struct ldb_message_element *el;
1930 int i, ret;
1931 struct lsa_EnumAccountRights r2;
1933 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, sid);
1934 if (sidstr == NULL) {
1935 return NT_STATUS_NO_MEMORY;
1938 msg = ldb_msg_new(mem_ctx);
1939 if (msg == NULL) {
1940 return NT_STATUS_NO_MEMORY;
1943 msg->dn = samdb_search_dn(state->sam_ldb, mem_ctx,
1944 NULL, "objectSid=%s", sidstr);
1945 if (msg->dn == NULL) {
1946 NTSTATUS status;
1947 if (ldb_flag == LDB_FLAG_MOD_DELETE) {
1948 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1950 status = samdb_create_foreign_security_principal(state->sam_ldb, mem_ctx,
1951 sid, &msg->dn);
1952 if (!NT_STATUS_IS_OK(status)) {
1953 return status;
1955 return NT_STATUS_NO_SUCH_USER;
1958 if (ldb_msg_add_empty(msg, "privilege", ldb_flag)) {
1959 return NT_STATUS_NO_MEMORY;
1962 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1963 NTSTATUS status;
1965 r2.in.handle = &state->handle->wire_handle;
1966 r2.in.sid = sid;
1967 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
1969 status = lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1970 if (!NT_STATUS_IS_OK(status)) {
1971 ZERO_STRUCTP(r2.out.rights);
1975 for (i=0;i<rights->count;i++) {
1976 if (sec_privilege_id(rights->names[i].string) == -1) {
1977 return NT_STATUS_NO_SUCH_PRIVILEGE;
1980 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1981 int j;
1982 for (j=0;j<r2.out.rights->count;j++) {
1983 if (strcasecmp_m(r2.out.rights->names[j].string,
1984 rights->names[i].string) == 0) {
1985 break;
1988 if (j != r2.out.rights->count) continue;
1991 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
1992 if (ret != LDB_SUCCESS) {
1993 return NT_STATUS_NO_MEMORY;
1997 el = ldb_msg_find_element(msg, "privilege");
1998 if (!el) {
1999 return NT_STATUS_OK;
2002 ret = samdb_modify(state->sam_ldb, mem_ctx, msg);
2003 if (ret != 0) {
2004 if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
2005 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2007 DEBUG(3, ("Could not %s attributes from %s: %s",
2008 ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add",
2009 ldb_dn_linearize(mem_ctx, msg->dn), ldb_errstring(state->sam_ldb)));
2010 return NT_STATUS_UNEXPECTED_IO_ERROR;
2013 return NT_STATUS_OK;
2017 lsa_AddPrivilegesToAccount
2019 static NTSTATUS lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2020 struct lsa_AddPrivilegesToAccount *r)
2022 struct lsa_RightSet rights;
2023 struct dcesrv_handle *h;
2024 struct lsa_account_state *astate;
2025 int i;
2027 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2029 astate = h->data;
2031 rights.count = r->in.privs->count;
2032 rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
2033 if (rights.names == NULL) {
2034 return NT_STATUS_NO_MEMORY;
2036 for (i=0;i<rights.count;i++) {
2037 int id = r->in.privs->set[i].luid.low;
2038 if (r->in.privs->set[i].luid.high) {
2039 return NT_STATUS_NO_SUCH_PRIVILEGE;
2041 rights.names[i].string = sec_privilege_name(id);
2042 if (rights.names[i].string == NULL) {
2043 return NT_STATUS_NO_SUCH_PRIVILEGE;
2047 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2048 LDB_FLAG_MOD_ADD, astate->account_sid,
2049 &rights);
2054 lsa_RemovePrivilegesFromAccount
2056 static NTSTATUS lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2057 struct lsa_RemovePrivilegesFromAccount *r)
2059 struct lsa_RightSet *rights;
2060 struct dcesrv_handle *h;
2061 struct lsa_account_state *astate;
2062 int i;
2064 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2066 astate = h->data;
2068 rights = talloc(mem_ctx, struct lsa_RightSet);
2070 if (r->in.remove_all == 1 &&
2071 r->in.privs == NULL) {
2072 struct lsa_EnumAccountRights r2;
2073 NTSTATUS status;
2075 r2.in.handle = &astate->policy->handle->wire_handle;
2076 r2.in.sid = astate->account_sid;
2077 r2.out.rights = rights;
2079 status = lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
2080 if (!NT_STATUS_IS_OK(status)) {
2081 return status;
2084 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2085 LDB_FLAG_MOD_DELETE, astate->account_sid,
2086 r2.out.rights);
2089 if (r->in.remove_all != 0) {
2090 return NT_STATUS_INVALID_PARAMETER;
2093 rights->count = r->in.privs->count;
2094 rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
2095 if (rights->names == NULL) {
2096 return NT_STATUS_NO_MEMORY;
2098 for (i=0;i<rights->count;i++) {
2099 int id = r->in.privs->set[i].luid.low;
2100 if (r->in.privs->set[i].luid.high) {
2101 return NT_STATUS_NO_SUCH_PRIVILEGE;
2103 rights->names[i].string = sec_privilege_name(id);
2104 if (rights->names[i].string == NULL) {
2105 return NT_STATUS_NO_SUCH_PRIVILEGE;
2109 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2110 LDB_FLAG_MOD_DELETE, astate->account_sid,
2111 rights);
2116 lsa_GetQuotasForAccount
2118 static NTSTATUS lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2119 struct lsa_GetQuotasForAccount *r)
2121 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2126 lsa_SetQuotasForAccount
2128 static NTSTATUS lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2129 struct lsa_SetQuotasForAccount *r)
2131 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2136 lsa_GetSystemAccessAccount
2138 static NTSTATUS lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2139 struct lsa_GetSystemAccessAccount *r)
2141 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2146 lsa_SetSystemAccessAccount
2148 static NTSTATUS lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2149 struct lsa_SetSystemAccessAccount *r)
2151 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2156 lsa_CreateSecret
2158 static NTSTATUS lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2159 struct lsa_CreateSecret *r)
2161 struct dcesrv_handle *policy_handle;
2162 struct lsa_policy_state *policy_state;
2163 struct lsa_secret_state *secret_state;
2164 struct dcesrv_handle *handle;
2165 struct ldb_message **msgs, *msg;
2166 const char *errstr;
2167 const char *attrs[] = {
2168 NULL
2171 const char *name;
2173 int ret;
2175 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2176 ZERO_STRUCTP(r->out.sec_handle);
2178 policy_state = policy_handle->data;
2180 if (!r->in.name.string) {
2181 return NT_STATUS_INVALID_PARAMETER;
2184 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2185 if (!secret_state) {
2186 return NT_STATUS_NO_MEMORY;
2188 secret_state->policy = policy_state;
2190 msg = ldb_msg_new(mem_ctx);
2191 if (msg == NULL) {
2192 return NT_STATUS_NO_MEMORY;
2195 if (strncmp("G$", r->in.name.string, 2) == 0) {
2196 const char *name2;
2197 name = &r->in.name.string[2];
2198 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
2199 secret_state->global = True;
2201 if (strlen(name) < 1) {
2202 return NT_STATUS_INVALID_PARAMETER;
2205 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
2206 /* search for the secret record */
2207 ret = gendb_search(secret_state->sam_ldb,
2208 mem_ctx, policy_state->system_dn, &msgs, attrs,
2209 "(&(cn=%s)(objectclass=secret))",
2210 name2);
2211 if (ret > 0) {
2212 return NT_STATUS_OBJECT_NAME_COLLISION;
2215 if (ret == -1) {
2216 DEBUG(0,("Failure searching for CN=%s: %s\n",
2217 name2, ldb_errstring(secret_state->sam_ldb)));
2218 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2221 msg->dn = ldb_dn_build_child(mem_ctx, "cn", name2, policy_state->system_dn);
2222 if (!name2 || !msg->dn) {
2223 return NT_STATUS_NO_MEMORY;
2226 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
2228 } else {
2229 secret_state->global = False;
2231 name = r->in.name.string;
2232 if (strlen(name) < 1) {
2233 return NT_STATUS_INVALID_PARAMETER;
2236 secret_state->sam_ldb = talloc_reference(secret_state, secrets_db_connect(mem_ctx));
2237 /* search for the secret record */
2238 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2239 ldb_dn_explode(mem_ctx, "cn=LSA Secrets"),
2240 &msgs, attrs,
2241 "(&(cn=%s)(objectclass=secret))",
2242 ldb_binary_encode_string(mem_ctx, name));
2243 if (ret > 0) {
2244 return NT_STATUS_OBJECT_NAME_COLLISION;
2247 if (ret == -1) {
2248 DEBUG(0,("Failure searching for CN=%s: %s\n",
2249 name, ldb_errstring(secret_state->sam_ldb)));
2250 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2253 msg->dn = ldb_dn_string_compose(mem_ctx, NULL, "cn=%s,cn=LSA Secrets", name);
2254 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
2257 /* pull in all the template attributes. Note this is always from the global samdb */
2258 ret = samdb_copy_template(secret_state->policy->sam_ldb, msg,
2259 "(&(cn=TemplateSecret)(objectclass=secretTemplate))", &errstr);
2260 if (ret != 0) {
2261 DEBUG(0,("Failed to load TemplateSecret from samdb: %s\n",
2262 errstr));
2263 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2266 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
2268 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
2270 /* create the secret */
2271 ret = samdb_add(secret_state->sam_ldb, mem_ctx, msg);
2272 if (ret != 0) {
2273 DEBUG(0,("Failed to create secret record %s: %s\n",
2274 ldb_dn_linearize(mem_ctx, msg->dn),
2275 ldb_errstring(secret_state->sam_ldb)));
2276 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2279 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2280 if (!handle) {
2281 return NT_STATUS_NO_MEMORY;
2284 handle->data = talloc_steal(handle, secret_state);
2286 secret_state->access_mask = r->in.access_mask;
2287 secret_state->policy = talloc_reference(secret_state, policy_state);
2289 *r->out.sec_handle = handle->wire_handle;
2291 return NT_STATUS_OK;
2296 lsa_OpenSecret
2298 static NTSTATUS lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2299 struct lsa_OpenSecret *r)
2301 struct dcesrv_handle *policy_handle;
2303 struct lsa_policy_state *policy_state;
2304 struct lsa_secret_state *secret_state;
2305 struct dcesrv_handle *handle;
2306 struct ldb_message **msgs;
2307 const char *attrs[] = {
2308 NULL
2311 const char *name;
2313 int ret;
2315 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2316 ZERO_STRUCTP(r->out.sec_handle);
2317 policy_state = policy_handle->data;
2319 if (!r->in.name.string) {
2320 return NT_STATUS_INVALID_PARAMETER;
2323 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2324 if (!secret_state) {
2325 return NT_STATUS_NO_MEMORY;
2327 secret_state->policy = policy_state;
2329 if (strncmp("G$", r->in.name.string, 2) == 0) {
2330 name = &r->in.name.string[2];
2331 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
2332 secret_state->global = True;
2334 if (strlen(name) < 1) {
2335 return NT_STATUS_INVALID_PARAMETER;
2338 /* search for the secret record */
2339 ret = gendb_search(secret_state->sam_ldb,
2340 mem_ctx, policy_state->system_dn, &msgs, attrs,
2341 "(&(cn=%s Secret)(objectclass=secret))",
2342 ldb_binary_encode_string(mem_ctx, name));
2343 if (ret == 0) {
2344 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2347 if (ret != 1) {
2348 DEBUG(0,("Found %d records matching DN %s\n", ret,
2349 ldb_dn_linearize(mem_ctx, policy_state->system_dn)));
2350 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2353 } else {
2354 secret_state->sam_ldb = talloc_reference(secret_state, secrets_db_connect(mem_ctx));
2356 secret_state->global = False;
2357 name = r->in.name.string;
2358 if (strlen(name) < 1) {
2359 return NT_STATUS_INVALID_PARAMETER;
2362 /* search for the secret record */
2363 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2364 ldb_dn_explode(mem_ctx, "cn=LSA Secrets"),
2365 &msgs, attrs,
2366 "(&(cn=%s)(objectclass=secret))",
2367 ldb_binary_encode_string(mem_ctx, name));
2368 if (ret == 0) {
2369 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2372 if (ret != 1) {
2373 DEBUG(0,("Found %d records matching DN %s\n", ret,
2374 ldb_dn_linearize(mem_ctx, policy_state->system_dn)));
2375 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2379 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
2381 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2382 if (!handle) {
2383 return NT_STATUS_NO_MEMORY;
2386 handle->data = talloc_steal(handle, secret_state);
2388 secret_state->access_mask = r->in.access_mask;
2389 secret_state->policy = talloc_reference(secret_state, policy_state);
2391 *r->out.sec_handle = handle->wire_handle;
2393 return NT_STATUS_OK;
2398 lsa_SetSecret
2400 static NTSTATUS lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2401 struct lsa_SetSecret *r)
2404 struct dcesrv_handle *h;
2405 struct lsa_secret_state *secret_state;
2406 struct ldb_message *msg;
2407 DATA_BLOB session_key;
2408 DATA_BLOB crypt_secret, secret;
2409 struct ldb_val val;
2410 int ret;
2411 NTSTATUS status = NT_STATUS_OK;
2413 struct timeval now = timeval_current();
2414 NTTIME nt_now = timeval_to_nttime(&now);
2416 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2418 secret_state = h->data;
2420 msg = ldb_msg_new(mem_ctx);
2421 if (msg == NULL) {
2422 return NT_STATUS_NO_MEMORY;
2425 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
2426 if (!msg->dn) {
2427 return NT_STATUS_NO_MEMORY;
2429 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2430 if (!NT_STATUS_IS_OK(status)) {
2431 return status;
2434 if (r->in.old_val) {
2435 /* Decrypt */
2436 crypt_secret.data = r->in.old_val->data;
2437 crypt_secret.length = r->in.old_val->size;
2439 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2440 if (!NT_STATUS_IS_OK(status)) {
2441 return status;
2444 val.data = secret.data;
2445 val.length = secret.length;
2447 /* set value */
2448 if (samdb_msg_add_value(secret_state->sam_ldb,
2449 mem_ctx, msg, "priorValue", &val) != 0) {
2450 return NT_STATUS_NO_MEMORY;
2453 /* set old value mtime */
2454 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2455 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
2456 return NT_STATUS_NO_MEMORY;
2459 if (!r->in.new_val) {
2460 /* This behaviour varies depending of if this is a local, or a global secret... */
2461 if (secret_state->global) {
2462 /* set old value mtime */
2463 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2464 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2465 return NT_STATUS_NO_MEMORY;
2467 } else {
2468 if (samdb_msg_add_delete(secret_state->sam_ldb,
2469 mem_ctx, msg, "currentValue")) {
2470 return NT_STATUS_NO_MEMORY;
2472 if (samdb_msg_add_delete(secret_state->sam_ldb,
2473 mem_ctx, msg, "lastSetTime")) {
2474 return NT_STATUS_NO_MEMORY;
2480 if (r->in.new_val) {
2481 /* Decrypt */
2482 crypt_secret.data = r->in.new_val->data;
2483 crypt_secret.length = r->in.new_val->size;
2485 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2486 if (!NT_STATUS_IS_OK(status)) {
2487 return status;
2490 val.data = secret.data;
2491 val.length = secret.length;
2493 /* set value */
2494 if (samdb_msg_add_value(secret_state->sam_ldb,
2495 mem_ctx, msg, "currentValue", &val) != 0) {
2496 return NT_STATUS_NO_MEMORY;
2499 /* set new value mtime */
2500 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2501 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2502 return NT_STATUS_NO_MEMORY;
2505 /* If the old value is not set, then migrate the
2506 * current value to the old value */
2507 if (!r->in.old_val) {
2508 const struct ldb_val *new_val;
2509 NTTIME last_set_time;
2510 struct ldb_message **res;
2511 const char *attrs[] = {
2512 "currentValue",
2513 "lastSetTime",
2514 NULL
2517 /* search for the secret record */
2518 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
2519 secret_state->secret_dn, &res, attrs);
2520 if (ret == 0) {
2521 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2524 if (ret != 1) {
2525 DEBUG(0,("Found %d records matching dn=%s\n", ret,
2526 ldb_dn_linearize(mem_ctx, secret_state->secret_dn)));
2527 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2530 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2531 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2533 if (new_val) {
2534 /* set value */
2535 if (samdb_msg_add_value(secret_state->sam_ldb,
2536 mem_ctx, msg, "priorValue",
2537 new_val) != 0) {
2538 return NT_STATUS_NO_MEMORY;
2542 /* set new value mtime */
2543 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2544 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2545 mem_ctx, msg, "priorSetTime", last_set_time) != 0) {
2546 return NT_STATUS_NO_MEMORY;
2552 /* modify the samdb record */
2553 ret = samdb_replace(secret_state->sam_ldb, mem_ctx, msg);
2554 if (ret != 0) {
2555 /* we really need samdb.c to return NTSTATUS */
2556 return NT_STATUS_UNSUCCESSFUL;
2559 return NT_STATUS_OK;
2564 lsa_QuerySecret
2566 static NTSTATUS lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2567 struct lsa_QuerySecret *r)
2569 struct dcesrv_handle *h;
2570 struct lsa_secret_state *secret_state;
2571 struct ldb_message *msg;
2572 DATA_BLOB session_key;
2573 DATA_BLOB crypt_secret, secret;
2574 int ret;
2575 struct ldb_message **res;
2576 const char *attrs[] = {
2577 "currentValue",
2578 "priorValue",
2579 "lastSetTime",
2580 "priorSetTime",
2581 NULL
2584 NTSTATUS nt_status;
2586 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2588 secret_state = h->data;
2590 /* pull all the user attributes */
2591 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2592 secret_state->secret_dn, &res, attrs);
2593 if (ret != 1) {
2594 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2596 msg = res[0];
2598 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2599 if (!NT_STATUS_IS_OK(nt_status)) {
2600 return nt_status;
2603 if (r->in.old_val) {
2604 const struct ldb_val *prior_val;
2605 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2606 if (!r->out.old_val) {
2607 return NT_STATUS_NO_MEMORY;
2609 /* Decrypt */
2610 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
2612 if (prior_val && prior_val->length) {
2613 secret.data = prior_val->data;
2614 secret.length = prior_val->length;
2616 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2617 if (!crypt_secret.length) {
2618 return NT_STATUS_NO_MEMORY;
2620 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2621 if (!r->out.old_val->buf) {
2622 return NT_STATUS_NO_MEMORY;
2624 r->out.old_val->buf->size = crypt_secret.length;
2625 r->out.old_val->buf->length = crypt_secret.length;
2626 r->out.old_val->buf->data = crypt_secret.data;
2630 if (r->in.old_mtime) {
2631 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2632 if (!r->out.old_mtime) {
2633 return NT_STATUS_NO_MEMORY;
2635 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
2638 if (r->in.new_val) {
2639 const struct ldb_val *new_val;
2640 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2641 if (!r->out.new_val) {
2642 return NT_STATUS_NO_MEMORY;
2645 /* Decrypt */
2646 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2648 if (new_val && new_val->length) {
2649 secret.data = new_val->data;
2650 secret.length = new_val->length;
2652 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2653 if (!crypt_secret.length) {
2654 return NT_STATUS_NO_MEMORY;
2656 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2657 if (!r->out.new_val->buf) {
2658 return NT_STATUS_NO_MEMORY;
2660 r->out.new_val->buf->length = crypt_secret.length;
2661 r->out.new_val->buf->size = crypt_secret.length;
2662 r->out.new_val->buf->data = crypt_secret.data;
2666 if (r->in.new_mtime) {
2667 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2668 if (!r->out.new_mtime) {
2669 return NT_STATUS_NO_MEMORY;
2671 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2674 return NT_STATUS_OK;
2679 lsa_LookupPrivValue
2681 static NTSTATUS lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
2682 TALLOC_CTX *mem_ctx,
2683 struct lsa_LookupPrivValue *r)
2685 struct dcesrv_handle *h;
2686 struct lsa_policy_state *state;
2687 int id;
2689 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2691 state = h->data;
2693 id = sec_privilege_id(r->in.name->string);
2694 if (id == -1) {
2695 return NT_STATUS_NO_SUCH_PRIVILEGE;
2698 r->out.luid->low = id;
2699 r->out.luid->high = 0;
2701 return NT_STATUS_OK;
2706 lsa_LookupPrivName
2708 static NTSTATUS lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
2709 TALLOC_CTX *mem_ctx,
2710 struct lsa_LookupPrivName *r)
2712 struct dcesrv_handle *h;
2713 struct lsa_policy_state *state;
2714 const char *privname;
2716 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2718 state = h->data;
2720 if (r->in.luid->high != 0) {
2721 return NT_STATUS_NO_SUCH_PRIVILEGE;
2724 privname = sec_privilege_name(r->in.luid->low);
2725 if (privname == NULL) {
2726 return NT_STATUS_NO_SUCH_PRIVILEGE;
2729 r->out.name = talloc(mem_ctx, struct lsa_StringLarge);
2730 if (r->out.name == NULL) {
2731 return NT_STATUS_NO_MEMORY;
2733 r->out.name->string = privname;
2735 return NT_STATUS_OK;
2740 lsa_LookupPrivDisplayName
2742 static NTSTATUS lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
2743 TALLOC_CTX *mem_ctx,
2744 struct lsa_LookupPrivDisplayName *r)
2746 struct dcesrv_handle *h;
2747 struct lsa_policy_state *state;
2748 int id;
2750 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2752 state = h->data;
2754 id = sec_privilege_id(r->in.name->string);
2755 if (id == -1) {
2756 return NT_STATUS_NO_SUCH_PRIVILEGE;
2759 r->out.disp_name = talloc(mem_ctx, struct lsa_StringLarge);
2760 if (r->out.disp_name == NULL) {
2761 return NT_STATUS_NO_MEMORY;
2764 r->out.disp_name->string = sec_privilege_display_name(id, r->in.language_id);
2765 if (r->out.disp_name->string == NULL) {
2766 return NT_STATUS_INTERNAL_ERROR;
2769 return NT_STATUS_OK;
2774 lsa_DeleteObject
2776 static NTSTATUS lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2777 struct lsa_DeleteObject *r)
2779 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2784 lsa_EnumAccountsWithUserRight
2786 static NTSTATUS lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
2787 TALLOC_CTX *mem_ctx,
2788 struct lsa_EnumAccountsWithUserRight *r)
2790 struct dcesrv_handle *h;
2791 struct lsa_policy_state *state;
2792 int ret, i;
2793 struct ldb_message **res;
2794 const char * const attrs[] = { "objectSid", NULL};
2795 const char *privname;
2797 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2799 state = h->data;
2801 if (r->in.name == NULL) {
2802 return NT_STATUS_NO_SUCH_PRIVILEGE;
2805 privname = r->in.name->string;
2806 if (sec_privilege_id(privname) == -1) {
2807 return NT_STATUS_NO_SUCH_PRIVILEGE;
2810 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
2811 "privilege=%s", privname);
2812 if (ret == -1) {
2813 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2815 if (ret == 0) {
2816 return NT_STATUS_NO_MORE_ENTRIES;
2819 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2820 if (r->out.sids->sids == NULL) {
2821 return NT_STATUS_NO_MEMORY;
2823 for (i=0;i<ret;i++) {
2824 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2825 res[i], "objectSid");
2826 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2828 r->out.sids->num_sids = ret;
2830 return NT_STATUS_OK;
2835 lsa_AddAccountRights
2837 static NTSTATUS lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
2838 TALLOC_CTX *mem_ctx,
2839 struct lsa_AddAccountRights *r)
2841 struct dcesrv_handle *h;
2842 struct lsa_policy_state *state;
2844 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2846 state = h->data;
2848 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2849 LDB_FLAG_MOD_ADD,
2850 r->in.sid, r->in.rights);
2855 lsa_RemoveAccountRights
2857 static NTSTATUS lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
2858 TALLOC_CTX *mem_ctx,
2859 struct lsa_RemoveAccountRights *r)
2861 struct dcesrv_handle *h;
2862 struct lsa_policy_state *state;
2864 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2866 state = h->data;
2868 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2869 LDB_FLAG_MOD_DELETE,
2870 r->in.sid, r->in.rights);
2875 lsa_StorePrivateData
2877 static NTSTATUS lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2878 struct lsa_StorePrivateData *r)
2880 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2885 lsa_RetrievePrivateData
2887 static NTSTATUS lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2888 struct lsa_RetrievePrivateData *r)
2890 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2895 lsa_GetUserName
2897 static NTSTATUS lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2898 struct lsa_GetUserName *r)
2900 NTSTATUS status = NT_STATUS_OK;
2901 const char *account_name;
2902 const char *authority_name;
2903 struct lsa_String *_account_name;
2904 struct lsa_StringPointer *_authority_name = NULL;
2906 /* this is what w2k3 does */
2907 r->out.account_name = r->in.account_name;
2908 r->out.authority_name = r->in.authority_name;
2910 if (r->in.account_name && r->in.account_name->string) {
2911 return NT_STATUS_INVALID_PARAMETER;
2914 if (r->in.authority_name &&
2915 r->in.authority_name->string &&
2916 r->in.authority_name->string->string) {
2917 return NT_STATUS_INVALID_PARAMETER;
2920 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
2921 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
2923 _account_name = talloc(mem_ctx, struct lsa_String);
2924 NT_STATUS_HAVE_NO_MEMORY(_account_name);
2925 _account_name->string = account_name;
2927 if (r->in.authority_name) {
2928 _authority_name = talloc(mem_ctx, struct lsa_StringPointer);
2929 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
2930 _authority_name->string = talloc(mem_ctx, struct lsa_String);
2931 NT_STATUS_HAVE_NO_MEMORY(_authority_name->string);
2932 _authority_name->string->string = authority_name;
2935 r->out.account_name = _account_name;
2936 r->out.authority_name = _authority_name;
2938 return status;
2942 lsa_SetInfoPolicy2
2944 static NTSTATUS lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
2945 TALLOC_CTX *mem_ctx,
2946 struct lsa_SetInfoPolicy2 *r)
2948 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2952 lsa_QueryDomainInformationPolicy
2954 static NTSTATUS lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2955 TALLOC_CTX *mem_ctx,
2956 struct lsa_QueryDomainInformationPolicy *r)
2958 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2962 lsa_SetDomInfoPolicy
2964 static NTSTATUS lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2965 TALLOC_CTX *mem_ctx,
2966 struct lsa_SetDomainInformationPolicy *r)
2968 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2972 lsa_TestCall
2974 static NTSTATUS lsa_TestCall(struct dcesrv_call_state *dce_call,
2975 TALLOC_CTX *mem_ctx,
2976 struct lsa_TestCall *r)
2978 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2982 lookup a SID for 1 name
2984 static NTSTATUS lsa_lookup_name(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
2985 const char *name, struct dom_sid **sid, uint32_t *atype)
2987 int ret;
2988 struct ldb_message **res;
2989 const char * const attrs[] = { "objectSid", "sAMAccountType", NULL};
2990 const char *p;
2992 p = strchr_m(name, '\\');
2993 if (p != NULL) {
2994 /* TODO: properly parse the domain prefix here, and use it to
2995 limit the search */
2996 name = p + 1;
2999 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs, "sAMAccountName=%s", ldb_binary_encode_string(mem_ctx, name));
3000 if (ret == 1) {
3001 *sid = samdb_result_dom_sid(mem_ctx, res[0], "objectSid");
3002 if (*sid == NULL) {
3003 return NT_STATUS_INVALID_SID;
3006 *atype = samdb_result_uint(res[0], "sAMAccountType", 0);
3008 return NT_STATUS_OK;
3011 /* need to add a call into sidmap to check for a allocated sid */
3013 return NT_STATUS_INVALID_SID;
3018 lsa_LookupNames3
3020 static NTSTATUS lsa_LookupNames3(struct dcesrv_call_state *dce_call,
3021 TALLOC_CTX *mem_ctx,
3022 struct lsa_LookupNames3 *r)
3024 struct lsa_policy_state *policy_state;
3025 struct dcesrv_handle *policy_handle;
3026 int i;
3027 NTSTATUS status = NT_STATUS_OK;
3029 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
3031 policy_state = policy_handle->data;
3033 r->out.domains = NULL;
3035 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
3036 if (r->out.domains == NULL) {
3037 return NT_STATUS_NO_MEMORY;
3040 r->out.sids = talloc_zero(mem_ctx, struct lsa_TransSidArray3);
3041 if (r->out.sids == NULL) {
3042 return NT_STATUS_NO_MEMORY;
3045 *r->out.count = 0;
3047 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid3,
3048 r->in.num_names);
3049 if (r->out.sids->sids == NULL) {
3050 return NT_STATUS_NO_MEMORY;
3053 for (i=0;i<r->in.num_names;i++) {
3054 const char *name = r->in.names[i].string;
3055 struct dom_sid *sid;
3056 uint32_t atype, rtype, sid_index;
3057 NTSTATUS status2;
3059 r->out.sids->count++;
3060 (*r->out.count)++;
3062 r->out.sids->sids[i].sid_type = SID_NAME_UNKNOWN;
3063 r->out.sids->sids[i].sid = NULL;
3064 r->out.sids->sids[i].sid_index = 0xFFFFFFFF;
3065 r->out.sids->sids[i].unknown = 0;
3067 status2 = lsa_lookup_name(policy_state, mem_ctx, name, &sid, &atype);
3068 if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
3069 status = STATUS_SOME_UNMAPPED;
3070 continue;
3073 rtype = samdb_atype_map(atype);
3074 if (rtype == SID_NAME_UNKNOWN) {
3075 status = STATUS_SOME_UNMAPPED;
3076 continue;
3079 status2 = lsa_authority_list(policy_state, mem_ctx, sid, r->out.domains, &sid_index);
3080 if (!NT_STATUS_IS_OK(status2)) {
3081 return status2;
3084 r->out.sids->sids[i].sid_type = rtype;
3085 r->out.sids->sids[i].sid = sid;
3086 r->out.sids->sids[i].sid_index = sid_index;
3087 r->out.sids->sids[i].unknown = 0;
3090 return status;
3094 lsa_LookupNames4
3096 Identical to LookupNames3, but doesn't take a policy handle
3099 static NTSTATUS lsa_LookupNames4(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3100 struct lsa_LookupNames4 *r)
3102 struct lsa_LookupNames3 r2;
3103 struct lsa_OpenPolicy2 pol;
3104 NTSTATUS status;
3105 struct dcesrv_handle *h;
3107 /* No policy handle on the wire, so make one up here */
3108 r2.in.handle = talloc(mem_ctx, struct policy_handle);
3109 if (!r2.in.handle) {
3110 return NT_STATUS_NO_MEMORY;
3113 pol.out.handle = r2.in.handle;
3114 pol.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3115 pol.in.attr = NULL;
3116 pol.in.system_name = NULL;
3117 status = lsa_OpenPolicy2(dce_call, mem_ctx, &pol);
3118 if (!NT_STATUS_IS_OK(status)) {
3119 return status;
3122 /* ensure this handle goes away at the end of this call */
3123 DCESRV_PULL_HANDLE(h, r2.in.handle, LSA_HANDLE_POLICY);
3124 talloc_steal(mem_ctx, h);
3126 r2.in.num_names = r->in.num_names;
3127 r2.in.names = r->in.names;
3128 r2.in.sids = r->in.sids;
3129 r2.in.count = r->in.count;
3130 r2.in.unknown1 = r->in.unknown1;
3131 r2.in.unknown2 = r->in.unknown2;
3132 r2.out.domains = r->out.domains;
3133 r2.out.sids = r->out.sids;
3134 r2.out.count = r->out.count;
3136 status = lsa_LookupNames3(dce_call, mem_ctx, &r2);
3137 if (dce_call->fault_code != 0) {
3138 return status;
3141 r->out.domains = r2.out.domains;
3142 r->out.sids = r2.out.sids;
3143 r->out.count = r2.out.count;
3144 return status;
3148 lsa_LookupNames2
3150 static NTSTATUS lsa_LookupNames2(struct dcesrv_call_state *dce_call,
3151 TALLOC_CTX *mem_ctx,
3152 struct lsa_LookupNames2 *r)
3154 struct lsa_policy_state *state;
3155 struct dcesrv_handle *h;
3156 int i;
3157 NTSTATUS status = NT_STATUS_OK;
3159 r->out.domains = NULL;
3161 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3163 state = h->data;
3165 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
3166 if (r->out.domains == NULL) {
3167 return NT_STATUS_NO_MEMORY;
3170 r->out.sids = talloc_zero(mem_ctx, struct lsa_TransSidArray2);
3171 if (r->out.sids == NULL) {
3172 return NT_STATUS_NO_MEMORY;
3175 *r->out.count = 0;
3177 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid2,
3178 r->in.num_names);
3179 if (r->out.sids->sids == NULL) {
3180 return NT_STATUS_NO_MEMORY;
3183 for (i=0;i<r->in.num_names;i++) {
3184 const char *name = r->in.names[i].string;
3185 struct dom_sid *sid;
3186 uint32_t atype, rtype, sid_index;
3187 NTSTATUS status2;
3189 r->out.sids->count++;
3190 (*r->out.count)++;
3192 r->out.sids->sids[i].sid_type = SID_NAME_UNKNOWN;
3193 r->out.sids->sids[i].rid = 0xFFFFFFFF;
3194 r->out.sids->sids[i].sid_index = 0xFFFFFFFF;
3195 r->out.sids->sids[i].unknown = 0;
3197 status2 = lsa_lookup_name(state, mem_ctx, name, &sid, &atype);
3198 if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
3199 status = STATUS_SOME_UNMAPPED;
3200 continue;
3203 rtype = samdb_atype_map(atype);
3204 if (rtype == SID_NAME_UNKNOWN) {
3205 status = STATUS_SOME_UNMAPPED;
3206 continue;
3209 status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
3210 if (!NT_STATUS_IS_OK(status2)) {
3211 return status2;
3214 r->out.sids->sids[i].sid_type = rtype;
3215 r->out.sids->sids[i].rid = sid->sub_auths[sid->num_auths-1];
3216 r->out.sids->sids[i].sid_index = sid_index;
3217 r->out.sids->sids[i].unknown = 0;
3220 return status;
3224 lsa_LookupNames
3226 static NTSTATUS lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3227 struct lsa_LookupNames *r)
3229 struct lsa_LookupNames2 r2;
3230 NTSTATUS status;
3231 int i;
3233 r2.in.handle = r->in.handle;
3234 r2.in.num_names = r->in.num_names;
3235 r2.in.names = r->in.names;
3236 r2.in.sids = NULL;
3237 r2.in.level = r->in.level;
3238 r2.in.count = r->in.count;
3239 r2.in.unknown1 = 0;
3240 r2.in.unknown2 = 0;
3241 r2.out.count = r->out.count;
3243 status = lsa_LookupNames2(dce_call, mem_ctx, &r2);
3244 if (dce_call->fault_code != 0) {
3245 return status;
3248 r->out.domains = r2.out.domains;
3249 r->out.sids = talloc(mem_ctx, struct lsa_TransSidArray);
3250 if (r->out.sids == NULL) {
3251 return NT_STATUS_NO_MEMORY;
3253 r->out.sids->count = r2.out.sids->count;
3254 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid,
3255 r->out.sids->count);
3256 if (r->out.sids->sids == NULL) {
3257 return NT_STATUS_NO_MEMORY;
3259 for (i=0;i<r->out.sids->count;i++) {
3260 r->out.sids->sids[i].sid_type = r2.out.sids->sids[i].sid_type;
3261 r->out.sids->sids[i].rid = r2.out.sids->sids[i].rid;
3262 r->out.sids->sids[i].sid_index = r2.out.sids->sids[i].sid_index;
3265 return status;
3269 lsa_CREDRWRITE
3271 static NTSTATUS lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3272 struct lsa_CREDRWRITE *r)
3274 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3279 lsa_CREDRREAD
3281 static NTSTATUS lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3282 struct lsa_CREDRREAD *r)
3284 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3289 lsa_CREDRENUMERATE
3291 static NTSTATUS lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3292 struct lsa_CREDRENUMERATE *r)
3294 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3299 lsa_CREDRWRITEDOMAINCREDENTIALS
3301 static NTSTATUS lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3302 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3304 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3309 lsa_CREDRREADDOMAINCREDENTIALS
3311 static NTSTATUS lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3312 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3314 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3319 lsa_CREDRDELETE
3321 static NTSTATUS lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3322 struct lsa_CREDRDELETE *r)
3324 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3329 lsa_CREDRGETTARGETINFO
3331 static NTSTATUS lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3332 struct lsa_CREDRGETTARGETINFO *r)
3334 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3339 lsa_CREDRPROFILELOADED
3341 static NTSTATUS lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3342 struct lsa_CREDRPROFILELOADED *r)
3344 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3349 lsa_CREDRGETSESSIONTYPES
3351 static NTSTATUS lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3352 struct lsa_CREDRGETSESSIONTYPES *r)
3354 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3359 lsa_LSARREGISTERAUDITEVENT
3361 static NTSTATUS lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3362 struct lsa_LSARREGISTERAUDITEVENT *r)
3364 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3369 lsa_LSARGENAUDITEVENT
3371 static NTSTATUS lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3372 struct lsa_LSARGENAUDITEVENT *r)
3374 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3379 lsa_LSARUNREGISTERAUDITEVENT
3381 static NTSTATUS lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3382 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3384 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3389 lsa_LSARQUERYFORESTTRUSTINFORMATION
3391 static NTSTATUS lsa_LSARQUERYFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3392 struct lsa_LSARQUERYFORESTTRUSTINFORMATION *r)
3394 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3399 lsa_LSARSETFORESTTRUSTINFORMATION
3401 static NTSTATUS lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3402 struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
3404 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3409 lsa_CREDRRENAME
3411 static NTSTATUS lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3412 struct lsa_CREDRRENAME *r)
3414 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3420 lsa_LSAROPENPOLICYSCE
3422 static NTSTATUS lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3423 struct lsa_LSAROPENPOLICYSCE *r)
3425 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3430 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
3432 static NTSTATUS lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3433 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
3435 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3440 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
3442 static NTSTATUS lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3443 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
3445 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3450 lsa_LSARADTREPORTSECURITYEVENT
3452 static NTSTATUS lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3453 struct lsa_LSARADTREPORTSECURITYEVENT *r)
3455 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3459 /* include the generated boilerplate */
3460 #include "librpc/gen_ndr/ndr_lsa_s.c"
3464 /*****************************************
3465 NOTE! The remaining calls below were
3466 removed in w2k3, so the DCESRV_FAULT()
3467 replies are the correct implementation. Do
3468 not try and fill these in with anything else
3469 ******************************************/
3472 dssetup_DsRoleDnsNameToFlatName
3474 static WERROR dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3475 struct dssetup_DsRoleDnsNameToFlatName *r)
3477 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3482 dssetup_DsRoleDcAsDc
3484 static WERROR dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3485 struct dssetup_DsRoleDcAsDc *r)
3487 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3492 dssetup_DsRoleDcAsReplica
3494 static WERROR dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3495 struct dssetup_DsRoleDcAsReplica *r)
3497 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3502 dssetup_DsRoleDemoteDc
3504 static WERROR dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3505 struct dssetup_DsRoleDemoteDc *r)
3507 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3512 dssetup_DsRoleGetDcOperationProgress
3514 static WERROR dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3515 struct dssetup_DsRoleGetDcOperationProgress *r)
3517 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3522 dssetup_DsRoleGetDcOperationResults
3524 static WERROR dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3525 struct dssetup_DsRoleGetDcOperationResults *r)
3527 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3532 dssetup_DsRoleCancel
3534 static WERROR dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3535 struct dssetup_DsRoleCancel *r)
3537 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3542 dssetup_DsRoleServerSaveStateForUpgrade
3544 static WERROR dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3545 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
3547 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3552 dssetup_DsRoleUpgradeDownlevelServer
3554 static WERROR dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3555 struct dssetup_DsRoleUpgradeDownlevelServer *r)
3557 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3562 dssetup_DsRoleAbortDownlevelServerUpgrade
3564 static WERROR dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3565 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
3567 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3571 /* include the generated boilerplate */
3572 #include "librpc/gen_ndr/ndr_dssetup_s.c"
3574 NTSTATUS dcerpc_server_lsa_init(void)
3576 NTSTATUS ret;
3578 ret = dcerpc_server_dssetup_init();
3579 if (!NT_STATUS_IS_OK(ret)) {
3580 return ret;
3582 ret = dcerpc_server_lsarpc_init();
3583 if (!NT_STATUS_IS_OK(ret)) {
3584 return ret;
3586 return ret;