s4:lsa RPC - fix up "gendb_*" result codes
[Samba/ekacnet.git] / source4 / rpc_server / lsa / dcesrv_lsa.c
blob7c92a1560ec7c79c92111bbd96b63405ff91a796
1 /* need access mask/acl implementation */
3 /*
4 Unix SMB/CIFS implementation.
6 endpoint server for the lsarpc pipe
8 Copyright (C) Andrew Tridgell 2004
9 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2008
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "rpc_server/lsa/lsa.h"
26 #include "system/kerberos.h"
27 #include "auth/kerberos/kerberos.h"
28 #include "librpc/gen_ndr/ndr_drsblobs.h"
29 #include "librpc/gen_ndr/ndr_lsa.h"
30 #include "../lib/crypto/crypto.h"
31 #include "lib/util/tsort.h"
34 this type allows us to distinguish handle types
38 state associated with a lsa_OpenAccount() operation
40 struct lsa_account_state {
41 struct lsa_policy_state *policy;
42 uint32_t access_mask;
43 struct dom_sid *account_sid;
48 state associated with a lsa_OpenSecret() operation
50 struct lsa_secret_state {
51 struct lsa_policy_state *policy;
52 uint32_t access_mask;
53 struct ldb_dn *secret_dn;
54 struct ldb_context *sam_ldb;
55 bool global;
59 state associated with a lsa_OpenTrustedDomain() operation
61 struct lsa_trusted_domain_state {
62 struct lsa_policy_state *policy;
63 uint32_t access_mask;
64 struct ldb_dn *trusted_domain_dn;
65 struct ldb_dn *trusted_domain_user_dn;
69 this is based on the samba3 function make_lsa_object_sd()
70 It uses the same logic, but with samba4 helper functions
72 static NTSTATUS dcesrv_build_lsa_sd(TALLOC_CTX *mem_ctx,
73 struct security_descriptor **sd,
74 struct dom_sid *sid,
75 uint32_t sid_access)
77 NTSTATUS status;
78 uint32_t rid;
79 struct dom_sid *domain_sid, *domain_admins_sid;
80 const char *domain_admins_sid_str, *sidstr;
81 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
83 status = dom_sid_split_rid(tmp_ctx, sid, &domain_sid, &rid);
84 NT_STATUS_NOT_OK_RETURN_AND_FREE(status, tmp_ctx);
86 domain_admins_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ADMINS);
87 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(domain_admins_sid, tmp_ctx);
89 domain_admins_sid_str = dom_sid_string(tmp_ctx, domain_admins_sid);
90 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(domain_admins_sid_str, tmp_ctx);
92 sidstr = dom_sid_string(tmp_ctx, sid);
93 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidstr, tmp_ctx);
95 *sd = security_descriptor_dacl_create(mem_ctx,
96 0, sidstr, NULL,
98 SID_WORLD,
99 SEC_ACE_TYPE_ACCESS_ALLOWED,
100 SEC_GENERIC_EXECUTE | SEC_GENERIC_READ, 0,
102 SID_BUILTIN_ADMINISTRATORS,
103 SEC_ACE_TYPE_ACCESS_ALLOWED,
104 SEC_GENERIC_ALL, 0,
106 SID_BUILTIN_ACCOUNT_OPERATORS,
107 SEC_ACE_TYPE_ACCESS_ALLOWED,
108 SEC_GENERIC_ALL, 0,
110 domain_admins_sid_str,
111 SEC_ACE_TYPE_ACCESS_ALLOWED,
112 SEC_GENERIC_ALL, 0,
114 sidstr,
115 SEC_ACE_TYPE_ACCESS_ALLOWED,
116 sid_access, 0,
118 NULL);
119 talloc_free(tmp_ctx);
121 NT_STATUS_HAVE_NO_MEMORY(*sd);
123 return NT_STATUS_OK;
127 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
128 TALLOC_CTX *mem_ctx,
129 struct lsa_EnumAccountRights *r);
131 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
132 TALLOC_CTX *mem_ctx,
133 struct lsa_policy_state *state,
134 int ldb_flag,
135 struct dom_sid *sid,
136 const struct lsa_RightSet *rights);
139 lsa_Close
141 static NTSTATUS dcesrv_lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
142 struct lsa_Close *r)
144 struct dcesrv_handle *h;
146 *r->out.handle = *r->in.handle;
148 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
150 talloc_free(h);
152 ZERO_STRUCTP(r->out.handle);
154 return NT_STATUS_OK;
159 lsa_Delete
161 static NTSTATUS dcesrv_lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
162 struct lsa_Delete *r)
164 return NT_STATUS_NOT_SUPPORTED;
169 lsa_DeleteObject
171 static NTSTATUS dcesrv_lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
172 struct lsa_DeleteObject *r)
174 struct dcesrv_handle *h;
175 int ret;
177 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
179 if (h->wire_handle.handle_type == LSA_HANDLE_SECRET) {
180 struct lsa_secret_state *secret_state = h->data;
182 /* Ensure user is permitted to delete this... */
183 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
185 case SECURITY_SYSTEM:
186 case SECURITY_ADMINISTRATOR:
187 break;
188 default:
189 /* Users and annonymous are not allowed delete things */
190 return NT_STATUS_ACCESS_DENIED;
193 ret = ldb_delete(secret_state->sam_ldb,
194 secret_state->secret_dn);
195 talloc_free(h);
196 if (ret != LDB_SUCCESS) {
197 return NT_STATUS_INVALID_HANDLE;
200 ZERO_STRUCTP(r->out.handle);
202 return NT_STATUS_OK;
203 } else if (h->wire_handle.handle_type == LSA_HANDLE_TRUSTED_DOMAIN) {
204 struct lsa_trusted_domain_state *trusted_domain_state =
205 talloc_get_type(h->data, struct lsa_trusted_domain_state);
206 ret = ldb_transaction_start(trusted_domain_state->policy->sam_ldb);
207 if (ret != LDB_SUCCESS) {
208 return NT_STATUS_INTERNAL_DB_CORRUPTION;
211 ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
212 trusted_domain_state->trusted_domain_dn);
213 if (ret != LDB_SUCCESS) {
214 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
215 return NT_STATUS_INVALID_HANDLE;
218 if (trusted_domain_state->trusted_domain_user_dn) {
219 ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
220 trusted_domain_state->trusted_domain_user_dn);
221 if (ret != LDB_SUCCESS) {
222 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
223 return NT_STATUS_INVALID_HANDLE;
227 ret = ldb_transaction_commit(trusted_domain_state->policy->sam_ldb);
228 if (ret != LDB_SUCCESS) {
229 return NT_STATUS_INTERNAL_DB_CORRUPTION;
231 talloc_free(h);
232 ZERO_STRUCTP(r->out.handle);
234 return NT_STATUS_OK;
235 } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
236 struct lsa_RightSet *rights;
237 struct lsa_account_state *astate;
238 struct lsa_EnumAccountRights r2;
239 NTSTATUS status;
241 rights = talloc(mem_ctx, struct lsa_RightSet);
243 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
245 astate = h->data;
247 r2.in.handle = &astate->policy->handle->wire_handle;
248 r2.in.sid = astate->account_sid;
249 r2.out.rights = rights;
251 /* dcesrv_lsa_EnumAccountRights takes a LSA_HANDLE_POLICY,
252 but we have a LSA_HANDLE_ACCOUNT here, so this call
253 will always fail */
254 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
255 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
256 return NT_STATUS_OK;
259 if (!NT_STATUS_IS_OK(status)) {
260 return status;
263 status = dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
264 LDB_FLAG_MOD_DELETE, astate->account_sid,
265 r2.out.rights);
266 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
267 return NT_STATUS_OK;
270 if (!NT_STATUS_IS_OK(status)) {
271 return status;
274 ZERO_STRUCTP(r->out.handle);
277 return NT_STATUS_INVALID_HANDLE;
282 lsa_EnumPrivs
284 static NTSTATUS dcesrv_lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
285 struct lsa_EnumPrivs *r)
287 struct dcesrv_handle *h;
288 struct lsa_policy_state *state;
289 uint32_t i;
290 const char *privname;
292 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
294 state = h->data;
296 i = *r->in.resume_handle;
297 if (i == 0) i = 1;
299 while ((privname = sec_privilege_name(i)) &&
300 r->out.privs->count < r->in.max_count) {
301 struct lsa_PrivEntry *e;
303 r->out.privs->privs = talloc_realloc(r->out.privs,
304 r->out.privs->privs,
305 struct lsa_PrivEntry,
306 r->out.privs->count+1);
307 if (r->out.privs->privs == NULL) {
308 return NT_STATUS_NO_MEMORY;
310 e = &r->out.privs->privs[r->out.privs->count];
311 e->luid.low = i;
312 e->luid.high = 0;
313 e->name.string = privname;
314 r->out.privs->count++;
315 i++;
318 *r->out.resume_handle = i;
320 return NT_STATUS_OK;
325 lsa_QuerySecObj
327 static NTSTATUS dcesrv_lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
328 struct lsa_QuerySecurity *r)
330 struct dcesrv_handle *h;
331 struct security_descriptor *sd;
332 NTSTATUS status;
333 struct dom_sid *sid;
335 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
337 sid = dce_call->conn->auth_state.session_info->security_token->user_sid;
339 if (h->wire_handle.handle_type == LSA_HANDLE_POLICY) {
340 status = dcesrv_build_lsa_sd(mem_ctx, &sd, sid, 0);
341 } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
342 status = dcesrv_build_lsa_sd(mem_ctx, &sd, sid,
343 LSA_ACCOUNT_ALL_ACCESS);
344 } else {
345 return NT_STATUS_INVALID_HANDLE;
347 NT_STATUS_NOT_OK_RETURN(status);
349 (*r->out.sdbuf) = talloc(mem_ctx, struct sec_desc_buf);
350 NT_STATUS_HAVE_NO_MEMORY(*r->out.sdbuf);
352 (*r->out.sdbuf)->sd = sd;
354 return NT_STATUS_OK;
359 lsa_SetSecObj
361 static NTSTATUS dcesrv_lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
362 struct lsa_SetSecObj *r)
364 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
369 lsa_ChangePassword
371 static NTSTATUS dcesrv_lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
372 struct lsa_ChangePassword *r)
374 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
378 dssetup_DsRoleGetPrimaryDomainInformation
380 This is not an LSA call, but is the only call left on the DSSETUP
381 pipe (after the pipe was truncated), and needs lsa_get_policy_state
383 static WERROR dcesrv_dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state *dce_call,
384 TALLOC_CTX *mem_ctx,
385 struct dssetup_DsRoleGetPrimaryDomainInformation *r)
387 union dssetup_DsRoleInfo *info;
389 info = talloc(mem_ctx, union dssetup_DsRoleInfo);
390 W_ERROR_HAVE_NO_MEMORY(info);
392 switch (r->in.level) {
393 case DS_ROLE_BASIC_INFORMATION:
395 enum dssetup_DsRole role = DS_ROLE_STANDALONE_SERVER;
396 uint32_t flags = 0;
397 const char *domain = NULL;
398 const char *dns_domain = NULL;
399 const char *forest = NULL;
400 struct GUID domain_guid;
401 struct lsa_policy_state *state;
403 NTSTATUS status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
404 if (!NT_STATUS_IS_OK(status)) {
405 return ntstatus_to_werror(status);
408 ZERO_STRUCT(domain_guid);
410 switch (lp_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
411 case ROLE_STANDALONE:
412 role = DS_ROLE_STANDALONE_SERVER;
413 break;
414 case ROLE_DOMAIN_MEMBER:
415 role = DS_ROLE_MEMBER_SERVER;
416 break;
417 case ROLE_DOMAIN_CONTROLLER:
418 if (samdb_is_pdc(state->sam_ldb)) {
419 role = DS_ROLE_PRIMARY_DC;
420 } else {
421 role = DS_ROLE_BACKUP_DC;
423 break;
426 switch (lp_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
427 case ROLE_STANDALONE:
428 domain = talloc_strdup(mem_ctx, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx));
429 W_ERROR_HAVE_NO_MEMORY(domain);
430 break;
431 case ROLE_DOMAIN_MEMBER:
432 domain = talloc_strdup(mem_ctx, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx));
433 W_ERROR_HAVE_NO_MEMORY(domain);
434 /* TODO: what is with dns_domain and forest and guid? */
435 break;
436 case ROLE_DOMAIN_CONTROLLER:
437 flags = DS_ROLE_PRIMARY_DS_RUNNING;
439 if (state->mixed_domain == 1) {
440 flags |= DS_ROLE_PRIMARY_DS_MIXED_MODE;
443 domain = state->domain_name;
444 dns_domain = state->domain_dns;
445 forest = state->forest_dns;
447 domain_guid = state->domain_guid;
448 flags |= DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT;
449 break;
452 info->basic.role = role;
453 info->basic.flags = flags;
454 info->basic.domain = domain;
455 info->basic.dns_domain = dns_domain;
456 info->basic.forest = forest;
457 info->basic.domain_guid = domain_guid;
459 r->out.info = info;
460 return WERR_OK;
462 case DS_ROLE_UPGRADE_STATUS:
464 info->upgrade.upgrading = DS_ROLE_NOT_UPGRADING;
465 info->upgrade.previous_role = DS_ROLE_PREVIOUS_UNKNOWN;
467 r->out.info = info;
468 return WERR_OK;
470 case DS_ROLE_OP_STATUS:
472 info->opstatus.status = DS_ROLE_OP_IDLE;
474 r->out.info = info;
475 return WERR_OK;
477 default:
478 return WERR_INVALID_PARAM;
481 return WERR_INVALID_PARAM;
485 fill in the AccountDomain info
487 static NTSTATUS dcesrv_lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
488 struct lsa_DomainInfo *info)
490 info->name.string = state->domain_name;
491 info->sid = state->domain_sid;
493 return NT_STATUS_OK;
497 fill in the DNS domain info
499 static NTSTATUS dcesrv_lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
500 struct lsa_DnsDomainInfo *info)
502 info->name.string = state->domain_name;
503 info->sid = state->domain_sid;
504 info->dns_domain.string = state->domain_dns;
505 info->dns_forest.string = state->forest_dns;
506 info->domain_guid = state->domain_guid;
508 return NT_STATUS_OK;
512 lsa_QueryInfoPolicy2
514 static NTSTATUS dcesrv_lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
515 struct lsa_QueryInfoPolicy2 *r)
517 struct lsa_policy_state *state;
518 struct dcesrv_handle *h;
519 union lsa_PolicyInformation *info;
521 *r->out.info = NULL;
523 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
525 state = h->data;
527 info = talloc_zero(mem_ctx, union lsa_PolicyInformation);
528 if (!info) {
529 return NT_STATUS_NO_MEMORY;
531 *r->out.info = info;
533 switch (r->in.level) {
534 case LSA_POLICY_INFO_AUDIT_LOG:
535 /* we don't need to fill in any of this */
536 ZERO_STRUCT(info->audit_log);
537 return NT_STATUS_OK;
538 case LSA_POLICY_INFO_AUDIT_EVENTS:
539 /* we don't need to fill in any of this */
540 ZERO_STRUCT(info->audit_events);
541 return NT_STATUS_OK;
542 case LSA_POLICY_INFO_PD:
543 /* we don't need to fill in any of this */
544 ZERO_STRUCT(info->pd);
545 return NT_STATUS_OK;
547 case LSA_POLICY_INFO_DOMAIN:
548 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->domain);
549 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
550 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->account_domain);
551 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
552 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->l_account_domain);
554 case LSA_POLICY_INFO_ROLE:
555 info->role.role = LSA_ROLE_PRIMARY;
556 return NT_STATUS_OK;
558 case LSA_POLICY_INFO_DNS:
559 case LSA_POLICY_INFO_DNS_INT:
560 return dcesrv_lsa_info_DNS(state, mem_ctx, &info->dns);
562 case LSA_POLICY_INFO_REPLICA:
563 ZERO_STRUCT(info->replica);
564 return NT_STATUS_OK;
566 case LSA_POLICY_INFO_QUOTA:
567 ZERO_STRUCT(info->quota);
568 return NT_STATUS_OK;
570 case LSA_POLICY_INFO_MOD:
571 case LSA_POLICY_INFO_AUDIT_FULL_SET:
572 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
573 /* windows gives INVALID_PARAMETER */
574 *r->out.info = NULL;
575 return NT_STATUS_INVALID_PARAMETER;
578 *r->out.info = NULL;
579 return NT_STATUS_INVALID_INFO_CLASS;
583 lsa_QueryInfoPolicy
585 static NTSTATUS dcesrv_lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
586 struct lsa_QueryInfoPolicy *r)
588 struct lsa_QueryInfoPolicy2 r2;
589 NTSTATUS status;
591 ZERO_STRUCT(r2);
593 r2.in.handle = r->in.handle;
594 r2.in.level = r->in.level;
595 r2.out.info = r->out.info;
597 status = dcesrv_lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
599 return status;
603 lsa_SetInfoPolicy
605 static NTSTATUS dcesrv_lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
606 struct lsa_SetInfoPolicy *r)
608 /* need to support this */
609 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
614 lsa_ClearAuditLog
616 static NTSTATUS dcesrv_lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
617 struct lsa_ClearAuditLog *r)
619 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
624 lsa_CreateAccount
626 This call does not seem to have any long-term effects, hence no database operations
628 we need to talk to the MS product group to find out what this account database means!
630 answer is that the lsa database is totally separate from the SAM and
631 ldap databases. We are going to need a separate ldb to store these
632 accounts. The SIDs on this account bear no relation to the SIDs in
635 static NTSTATUS dcesrv_lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
636 struct lsa_CreateAccount *r)
638 struct lsa_account_state *astate;
640 struct lsa_policy_state *state;
641 struct dcesrv_handle *h, *ah;
643 ZERO_STRUCTP(r->out.acct_handle);
645 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
647 state = h->data;
649 astate = talloc(dce_call->conn, struct lsa_account_state);
650 if (astate == NULL) {
651 return NT_STATUS_NO_MEMORY;
654 astate->account_sid = dom_sid_dup(astate, r->in.sid);
655 if (astate->account_sid == NULL) {
656 talloc_free(astate);
657 return NT_STATUS_NO_MEMORY;
660 astate->policy = talloc_reference(astate, state);
661 astate->access_mask = r->in.access_mask;
663 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
664 if (!ah) {
665 talloc_free(astate);
666 return NT_STATUS_NO_MEMORY;
669 ah->data = talloc_steal(ah, astate);
671 *r->out.acct_handle = ah->wire_handle;
673 return NT_STATUS_OK;
678 lsa_EnumAccounts
680 static NTSTATUS dcesrv_lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
681 struct lsa_EnumAccounts *r)
683 struct dcesrv_handle *h;
684 struct lsa_policy_state *state;
685 int ret;
686 struct ldb_message **res;
687 const char * const attrs[] = { "objectSid", NULL};
688 uint32_t count, i;
690 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
692 state = h->data;
694 /* NOTE: This call must only return accounts that have at least
695 one privilege set
697 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
698 "(&(objectSid=*)(privilege=*))");
699 if (ret < 0) {
700 return NT_STATUS_INTERNAL_DB_CORRUPTION;
703 if (*r->in.resume_handle >= ret) {
704 return NT_STATUS_NO_MORE_ENTRIES;
707 count = ret - *r->in.resume_handle;
708 if (count > r->in.num_entries) {
709 count = r->in.num_entries;
712 if (count == 0) {
713 return NT_STATUS_NO_MORE_ENTRIES;
716 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, count);
717 if (r->out.sids->sids == NULL) {
718 return NT_STATUS_NO_MEMORY;
721 for (i=0;i<count;i++) {
722 r->out.sids->sids[i].sid =
723 samdb_result_dom_sid(r->out.sids->sids,
724 res[i + *r->in.resume_handle],
725 "objectSid");
726 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
729 r->out.sids->num_sids = count;
730 *r->out.resume_handle = count + *r->in.resume_handle;
732 return NT_STATUS_OK;
738 lsa_CreateTrustedDomainEx2
740 static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dce_call,
741 TALLOC_CTX *mem_ctx,
742 struct lsa_CreateTrustedDomainEx2 *r,
743 int op)
745 struct dcesrv_handle *policy_handle;
746 struct lsa_policy_state *policy_state;
747 struct lsa_trusted_domain_state *trusted_domain_state;
748 struct dcesrv_handle *handle;
749 struct ldb_message **msgs, *msg, *msg_user;
750 const char *attrs[] = {
751 NULL
753 const char *netbios_name;
754 const char *dns_name;
755 const char *name;
756 DATA_BLOB session_key = data_blob(NULL, 0);
757 DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob;
758 struct trustDomainPasswords auth_struct;
759 int ret;
760 NTSTATUS nt_status;
761 enum ndr_err_code ndr_err;
762 struct ldb_context *sam_ldb;
764 DCESRV_PULL_HANDLE(policy_handle, r->in.policy_handle, LSA_HANDLE_POLICY);
765 ZERO_STRUCTP(r->out.trustdom_handle);
767 policy_state = policy_handle->data;
768 sam_ldb = policy_state->sam_ldb;
770 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
771 if (!NT_STATUS_IS_OK(nt_status)) {
772 return nt_status;
775 netbios_name = r->in.info->netbios_name.string;
776 if (!netbios_name) {
777 return NT_STATUS_INVALID_PARAMETER;
780 dns_name = r->in.info->domain_name.string;
782 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
783 if (!trusted_domain_state) {
784 return NT_STATUS_NO_MEMORY;
786 trusted_domain_state->policy = policy_state;
788 if (strcasecmp(netbios_name, "BUILTIN") == 0
789 || (dns_name && strcasecmp(dns_name, "BUILTIN") == 0)
790 || (dom_sid_in_domain(policy_state->builtin_sid, r->in.info->sid))) {
791 return NT_STATUS_INVALID_PARAMETER;;
794 if (strcasecmp(netbios_name, policy_state->domain_name) == 0
795 || strcasecmp(netbios_name, policy_state->domain_dns) == 0
796 || (dns_name && strcasecmp(dns_name, policy_state->domain_dns) == 0)
797 || (dns_name && strcasecmp(dns_name, policy_state->domain_name) == 0)
798 || (dom_sid_equal(policy_state->domain_sid, r->in.info->sid))) {
799 return NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED;
802 /* While this is a REF pointer, some of the functions that wrap this don't provide this */
803 if (op == NDR_LSA_CREATETRUSTEDDOMAIN) {
804 /* No secrets are created at this time, for this function */
805 auth_struct.outgoing.count = 0;
806 auth_struct.incoming.count = 0;
807 } else {
808 auth_blob = data_blob_const(r->in.auth_info->auth_blob.data, r->in.auth_info->auth_blob.size);
809 arcfour_crypt_blob(auth_blob.data, auth_blob.length, &session_key);
810 ndr_err = ndr_pull_struct_blob(&auth_blob, mem_ctx,
811 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
812 &auth_struct,
813 (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
814 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
815 return NT_STATUS_INVALID_PARAMETER;
818 if (op == NDR_LSA_CREATETRUSTEDDOMAINEX) {
819 if (auth_struct.incoming.count > 1) {
820 return NT_STATUS_INVALID_PARAMETER;
825 if (auth_struct.incoming.count) {
826 uint32_t i;
827 struct trustAuthInOutBlob incoming;
829 incoming.count = auth_struct.incoming.count;
830 incoming.current = talloc(mem_ctx, struct AuthenticationInformationArray);
831 if (!incoming.current) {
832 return NT_STATUS_NO_MEMORY;
835 incoming.current->array = *auth_struct.incoming.current;
836 if (!incoming.current->array) {
837 return NT_STATUS_NO_MEMORY;
840 incoming.previous = talloc(mem_ctx, struct AuthenticationInformationArray);
841 if (!incoming.previous) {
842 return NT_STATUS_NO_MEMORY;
844 incoming.previous->array = talloc_array(mem_ctx, struct AuthenticationInformation, incoming.count);
845 if (!incoming.previous->array) {
846 return NT_STATUS_NO_MEMORY;
849 for (i = 0; i < incoming.count; i++) {
850 incoming.previous->array[i].LastUpdateTime = 0;
851 incoming.previous->array[i].AuthType = 0;
853 ndr_err = ndr_push_struct_blob(&trustAuthIncoming, mem_ctx,
854 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
855 &incoming,
856 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
857 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
858 return NT_STATUS_INVALID_PARAMETER;
860 } else {
861 trustAuthIncoming = data_blob(NULL, 0);
864 if (auth_struct.outgoing.count) {
865 uint32_t i;
866 struct trustAuthInOutBlob outgoing;
868 outgoing.count = auth_struct.outgoing.count;
869 outgoing.current = talloc(mem_ctx, struct AuthenticationInformationArray);
870 if (!outgoing.current) {
871 return NT_STATUS_NO_MEMORY;
874 outgoing.current->array = *auth_struct.outgoing.current;
875 if (!outgoing.current->array) {
876 return NT_STATUS_NO_MEMORY;
879 outgoing.previous = talloc(mem_ctx, struct AuthenticationInformationArray);
880 if (!outgoing.previous) {
881 return NT_STATUS_NO_MEMORY;
883 outgoing.previous->array = talloc_array(mem_ctx, struct AuthenticationInformation, outgoing.count);
884 if (!outgoing.previous->array) {
885 return NT_STATUS_NO_MEMORY;
888 for (i = 0; i < outgoing.count; i++) {
889 outgoing.previous->array[i].LastUpdateTime = 0;
890 outgoing.previous->array[i].AuthType = 0;
892 ndr_err = ndr_push_struct_blob(&trustAuthOutgoing, mem_ctx,
893 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
894 &outgoing,
895 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
896 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
897 return NT_STATUS_INVALID_PARAMETER;
899 } else {
900 trustAuthOutgoing = data_blob(NULL, 0);
903 ret = ldb_transaction_start(sam_ldb);
904 if (ret != LDB_SUCCESS) {
905 return NT_STATUS_INTERNAL_DB_CORRUPTION;
908 if (dns_name) {
909 char *dns_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
910 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
911 /* search for the trusted_domain record */
912 ret = gendb_search(sam_ldb,
913 mem_ctx, policy_state->system_dn, &msgs, attrs,
914 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s)(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))",
915 dns_encoded, dns_encoded, dns_encoded, netbios_encoded, netbios_encoded, netbios_encoded);
916 if (ret > 0) {
917 ldb_transaction_cancel(sam_ldb);
918 return NT_STATUS_OBJECT_NAME_COLLISION;
920 } else {
921 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
922 /* search for the trusted_domain record */
923 ret = gendb_search(sam_ldb,
924 mem_ctx, policy_state->system_dn, &msgs, attrs,
925 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))",
926 netbios_encoded, netbios_encoded, netbios_encoded);
927 if (ret > 0) {
928 ldb_transaction_cancel(sam_ldb);
929 return NT_STATUS_OBJECT_NAME_COLLISION;
933 if (ret < 0 ) {
934 ldb_transaction_cancel(sam_ldb);
935 return NT_STATUS_INTERNAL_DB_CORRUPTION;
938 name = dns_name ? dns_name : netbios_name;
940 msg = ldb_msg_new(mem_ctx);
941 if (msg == NULL) {
942 return NT_STATUS_NO_MEMORY;
945 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
946 if ( ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name)) {
947 ldb_transaction_cancel(sam_ldb);
948 return NT_STATUS_NO_MEMORY;
951 samdb_msg_add_string(sam_ldb, mem_ctx, msg, "flatname", netbios_name);
953 if (r->in.info->sid) {
954 ret = samdb_msg_add_dom_sid(sam_ldb, mem_ctx, msg, "securityIdentifier", r->in.info->sid);
955 if (ret != LDB_SUCCESS) {
956 ldb_transaction_cancel(sam_ldb);
957 return NT_STATUS_INVALID_PARAMETER;
961 samdb_msg_add_string(sam_ldb, mem_ctx, msg, "objectClass", "trustedDomain");
963 samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustType", r->in.info->trust_type);
965 samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustAttributes", r->in.info->trust_attributes);
967 samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustDirection", r->in.info->trust_direction);
969 if (dns_name) {
970 samdb_msg_add_string(sam_ldb, mem_ctx, msg, "trustPartner", dns_name);
973 if (trustAuthIncoming.data) {
974 ret = ldb_msg_add_value(msg, "trustAuthIncoming", &trustAuthIncoming, NULL);
975 if (ret != LDB_SUCCESS) {
976 ldb_transaction_cancel(sam_ldb);
977 return NT_STATUS_NO_MEMORY;
980 if (trustAuthOutgoing.data) {
981 ret = ldb_msg_add_value(msg, "trustAuthOutgoing", &trustAuthOutgoing, NULL);
982 if (ret != LDB_SUCCESS) {
983 ldb_transaction_cancel(sam_ldb);
984 return NT_STATUS_NO_MEMORY;
988 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
990 /* create the trusted_domain */
991 ret = ldb_add(sam_ldb, msg);
992 switch (ret) {
993 case LDB_SUCCESS:
994 break;
995 case LDB_ERR_ENTRY_ALREADY_EXISTS:
996 ldb_transaction_cancel(sam_ldb);
997 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
998 ldb_dn_get_linearized(msg->dn),
999 ldb_errstring(sam_ldb)));
1000 return NT_STATUS_DOMAIN_EXISTS;
1001 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1002 ldb_transaction_cancel(sam_ldb);
1003 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
1004 ldb_dn_get_linearized(msg->dn),
1005 ldb_errstring(sam_ldb)));
1006 return NT_STATUS_ACCESS_DENIED;
1007 default:
1008 ldb_transaction_cancel(sam_ldb);
1009 DEBUG(0,("Failed to create user record %s: %s\n",
1010 ldb_dn_get_linearized(msg->dn),
1011 ldb_errstring(sam_ldb)));
1012 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1015 if (r->in.info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1016 msg_user = ldb_msg_new(mem_ctx);
1017 if (msg_user == NULL) {
1018 ldb_transaction_cancel(sam_ldb);
1019 return NT_STATUS_NO_MEMORY;
1022 /* Inbound trusts must also create a cn=users object to match */
1024 trusted_domain_state->trusted_domain_user_dn = msg_user->dn
1025 = ldb_dn_copy(trusted_domain_state, policy_state->domain_dn);
1026 if ( ! ldb_dn_add_child_fmt(msg_user->dn, "cn=users")) {
1027 ldb_transaction_cancel(sam_ldb);
1028 return NT_STATUS_NO_MEMORY;
1031 if ( ! ldb_dn_add_child_fmt(msg_user->dn, "cn=%s", netbios_name)) {
1032 ldb_transaction_cancel(sam_ldb);
1033 return NT_STATUS_NO_MEMORY;
1036 ldb_msg_add_string(msg_user, "objectClass", "user");
1038 ldb_msg_add_steal_string(msg_user, "samAccountName",
1039 talloc_asprintf(mem_ctx, "%s$", netbios_name));
1041 if (samdb_msg_add_uint(sam_ldb, mem_ctx, msg_user,
1042 "userAccountControl",
1043 UF_INTERDOMAIN_TRUST_ACCOUNT) != 0) {
1044 ldb_transaction_cancel(sam_ldb);
1045 return NT_STATUS_NO_MEMORY;
1048 if (auth_struct.incoming.count) {
1049 uint32_t i;
1050 for (i=0; i < auth_struct.incoming.count; i++ ) {
1051 if (auth_struct.incoming.current[i]->AuthType == TRUST_AUTH_TYPE_NT4OWF) {
1052 samdb_msg_add_hash(sam_ldb,
1053 mem_ctx, msg_user, "unicodePwd",
1054 &auth_struct.incoming.current[i]->AuthInfo.nt4owf.password);
1055 } else if (auth_struct.incoming.current[i]->AuthType == TRUST_AUTH_TYPE_CLEAR) {
1056 DATA_BLOB new_password = data_blob_const(auth_struct.incoming.current[i]->AuthInfo.clear.password,
1057 auth_struct.incoming.current[i]->AuthInfo.clear.size);
1058 ret = ldb_msg_add_value(msg_user, "clearTextPassword", &new_password, NULL);
1059 if (ret != LDB_SUCCESS) {
1060 ldb_transaction_cancel(sam_ldb);
1061 return NT_STATUS_NO_MEMORY;
1067 /* create the cn=users trusted_domain account */
1068 ret = ldb_add(sam_ldb, msg_user);
1069 switch (ret) {
1070 case LDB_SUCCESS:
1071 break;
1072 case LDB_ERR_ENTRY_ALREADY_EXISTS:
1073 ldb_transaction_cancel(sam_ldb);
1074 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
1075 ldb_dn_get_linearized(msg_user->dn),
1076 ldb_errstring(sam_ldb)));
1077 return NT_STATUS_DOMAIN_EXISTS;
1078 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1079 ldb_transaction_cancel(sam_ldb);
1080 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
1081 ldb_dn_get_linearized(msg_user->dn),
1082 ldb_errstring(sam_ldb)));
1083 return NT_STATUS_ACCESS_DENIED;
1084 default:
1085 ldb_transaction_cancel(sam_ldb);
1086 DEBUG(0,("Failed to create user record %s: %s\n",
1087 ldb_dn_get_linearized(msg_user->dn),
1088 ldb_errstring(sam_ldb)));
1089 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1093 ret = ldb_transaction_commit(sam_ldb);
1094 if (ret != LDB_SUCCESS) {
1095 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1098 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1099 if (!handle) {
1100 return NT_STATUS_NO_MEMORY;
1103 handle->data = talloc_steal(handle, trusted_domain_state);
1105 trusted_domain_state->access_mask = r->in.access_mask;
1106 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1108 *r->out.trustdom_handle = handle->wire_handle;
1110 return NT_STATUS_OK;
1114 lsa_CreateTrustedDomainEx2
1116 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
1117 TALLOC_CTX *mem_ctx,
1118 struct lsa_CreateTrustedDomainEx2 *r)
1120 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, r, NDR_LSA_CREATETRUSTEDDOMAINEX2);
1123 lsa_CreateTrustedDomainEx
1125 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
1126 TALLOC_CTX *mem_ctx,
1127 struct lsa_CreateTrustedDomainEx *r)
1129 struct lsa_CreateTrustedDomainEx2 r2;
1131 r2.in.policy_handle = r->in.policy_handle;
1132 r2.in.info = r->in.info;
1133 r2.in.auth_info = r->in.auth_info;
1134 r2.out.trustdom_handle = r->out.trustdom_handle;
1135 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAINEX);
1139 lsa_CreateTrustedDomain
1141 static NTSTATUS dcesrv_lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1142 struct lsa_CreateTrustedDomain *r)
1144 struct lsa_CreateTrustedDomainEx2 r2;
1146 r2.in.policy_handle = r->in.policy_handle;
1147 r2.in.info = talloc(mem_ctx, struct lsa_TrustDomainInfoInfoEx);
1148 if (!r2.in.info) {
1149 return NT_STATUS_NO_MEMORY;
1152 r2.in.info->domain_name.string = NULL;
1153 r2.in.info->netbios_name = r->in.info->name;
1154 r2.in.info->sid = r->in.info->sid;
1155 r2.in.info->trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
1156 r2.in.info->trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1157 r2.in.info->trust_attributes = 0;
1159 r2.in.access_mask = r->in.access_mask;
1160 r2.out.trustdom_handle = r->out.trustdom_handle;
1162 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAIN);
1167 lsa_OpenTrustedDomain
1169 static NTSTATUS dcesrv_lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1170 struct lsa_OpenTrustedDomain *r)
1172 struct dcesrv_handle *policy_handle;
1174 struct lsa_policy_state *policy_state;
1175 struct lsa_trusted_domain_state *trusted_domain_state;
1176 struct dcesrv_handle *handle;
1177 struct ldb_message **msgs;
1178 const char *attrs[] = {
1179 "trustDirection",
1180 "flatname",
1181 NULL
1184 const char *sid_string;
1185 int ret;
1187 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1188 ZERO_STRUCTP(r->out.trustdom_handle);
1189 policy_state = policy_handle->data;
1191 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
1192 if (!trusted_domain_state) {
1193 return NT_STATUS_NO_MEMORY;
1195 trusted_domain_state->policy = policy_state;
1197 sid_string = dom_sid_string(mem_ctx, r->in.sid);
1198 if (!sid_string) {
1199 return NT_STATUS_NO_MEMORY;
1202 /* search for the trusted_domain record */
1203 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1204 mem_ctx, policy_state->system_dn, &msgs, attrs,
1205 "(&(securityIdentifier=%s)(objectclass=trustedDomain))",
1206 sid_string);
1207 if (ret == 0) {
1208 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1211 if (ret != 1) {
1212 DEBUG(0,("Found %d records matching DN %s\n", ret,
1213 ldb_dn_get_linearized(policy_state->system_dn)));
1214 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1217 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
1219 trusted_domain_state->trusted_domain_user_dn = NULL;
1221 if (ldb_msg_find_attr_as_int(msgs[0], "trustDirection", 0) & LSA_TRUST_DIRECTION_INBOUND) {
1222 const char *flatname = ldb_binary_encode_string(mem_ctx, ldb_msg_find_attr_as_string(msgs[0], "flatname", NULL));
1223 /* search for the trusted_domain record */
1224 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1225 mem_ctx, policy_state->domain_dn, &msgs, attrs,
1226 "(&(samaccountname=%s$)(objectclass=user)(userAccountControl:1.2.840.113556.1.4.803:=%d))",
1227 flatname, UF_INTERDOMAIN_TRUST_ACCOUNT);
1228 if (ret == 1) {
1229 trusted_domain_state->trusted_domain_user_dn = talloc_steal(trusted_domain_state, msgs[0]->dn);
1232 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1233 if (!handle) {
1234 return NT_STATUS_NO_MEMORY;
1237 handle->data = talloc_steal(handle, trusted_domain_state);
1239 trusted_domain_state->access_mask = r->in.access_mask;
1240 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1242 *r->out.trustdom_handle = handle->wire_handle;
1244 return NT_STATUS_OK;
1249 lsa_OpenTrustedDomainByName
1251 static NTSTATUS dcesrv_lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
1252 TALLOC_CTX *mem_ctx,
1253 struct lsa_OpenTrustedDomainByName *r)
1255 struct dcesrv_handle *policy_handle;
1257 struct lsa_policy_state *policy_state;
1258 struct lsa_trusted_domain_state *trusted_domain_state;
1259 struct dcesrv_handle *handle;
1260 struct ldb_message **msgs;
1261 const char *attrs[] = {
1262 NULL
1264 char *td_name;
1265 int ret;
1267 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1268 ZERO_STRUCTP(r->out.trustdom_handle);
1269 policy_state = policy_handle->data;
1271 if (!r->in.name.string) {
1272 return NT_STATUS_INVALID_PARAMETER;
1275 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
1276 if (!trusted_domain_state) {
1277 return NT_STATUS_NO_MEMORY;
1279 trusted_domain_state->policy = policy_state;
1281 /* search for the trusted_domain record */
1282 td_name = ldb_binary_encode_string(mem_ctx, r->in.name.string);
1283 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1284 mem_ctx, policy_state->system_dn, &msgs, attrs,
1285 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s))"
1286 "(objectclass=trustedDomain))",
1287 td_name, td_name, td_name);
1288 if (ret == 0) {
1289 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1292 if (ret != 1) {
1293 DEBUG(0,("Found %d records matching DN %s\n", ret,
1294 ldb_dn_get_linearized(policy_state->system_dn)));
1295 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1298 /* TODO: perform access checks */
1300 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
1302 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1303 if (!handle) {
1304 return NT_STATUS_NO_MEMORY;
1307 handle->data = talloc_steal(handle, trusted_domain_state);
1309 trusted_domain_state->access_mask = r->in.access_mask;
1310 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1312 *r->out.trustdom_handle = handle->wire_handle;
1314 return NT_STATUS_OK;
1320 lsa_SetTrustedDomainInfo
1322 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1323 struct lsa_SetTrustedDomainInfo *r)
1325 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1331 lsa_SetInfomrationTrustedDomain
1333 static NTSTATUS dcesrv_lsa_SetInformationTrustedDomain(struct dcesrv_call_state *dce_call,
1334 TALLOC_CTX *mem_ctx,
1335 struct lsa_SetInformationTrustedDomain *r)
1337 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1342 lsa_DeleteTrustedDomain
1344 static NTSTATUS dcesrv_lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1345 struct lsa_DeleteTrustedDomain *r)
1347 NTSTATUS status;
1348 struct lsa_OpenTrustedDomain opn;
1349 struct lsa_DeleteObject del;
1350 struct dcesrv_handle *h;
1352 opn.in.handle = r->in.handle;
1353 opn.in.sid = r->in.dom_sid;
1354 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1355 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1356 if (!opn.out.trustdom_handle) {
1357 return NT_STATUS_NO_MEMORY;
1359 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
1360 if (!NT_STATUS_IS_OK(status)) {
1361 return status;
1364 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
1365 talloc_steal(mem_ctx, h);
1367 del.in.handle = opn.out.trustdom_handle;
1368 del.out.handle = opn.out.trustdom_handle;
1369 status = dcesrv_lsa_DeleteObject(dce_call, mem_ctx, &del);
1370 if (!NT_STATUS_IS_OK(status)) {
1371 return status;
1373 return NT_STATUS_OK;
1376 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx,
1377 struct ldb_message *msg,
1378 struct lsa_TrustDomainInfoInfoEx *info_ex)
1380 info_ex->domain_name.string
1381 = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
1382 info_ex->netbios_name.string
1383 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1384 info_ex->sid
1385 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1386 info_ex->trust_direction
1387 = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
1388 info_ex->trust_type
1389 = ldb_msg_find_attr_as_int(msg, "trustType", 0);
1390 info_ex->trust_attributes
1391 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);
1392 return NT_STATUS_OK;
1396 lsa_QueryTrustedDomainInfo
1398 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1399 struct lsa_QueryTrustedDomainInfo *r)
1401 union lsa_TrustedDomainInfo *info = NULL;
1402 struct dcesrv_handle *h;
1403 struct lsa_trusted_domain_state *trusted_domain_state;
1404 struct ldb_message *msg;
1405 int ret;
1406 struct ldb_message **res;
1407 const char *attrs[] = {
1408 "flatname",
1409 "trustPartner",
1410 "securityIdentifier",
1411 "trustDirection",
1412 "trustType",
1413 "trustAttributes",
1414 "msDs-supportedEncryptionTypes",
1415 NULL
1418 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
1420 trusted_domain_state = talloc_get_type(h->data, struct lsa_trusted_domain_state);
1422 /* pull all the user attributes */
1423 ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
1424 trusted_domain_state->trusted_domain_dn, &res, attrs);
1425 if (ret != 1) {
1426 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1428 msg = res[0];
1430 info = talloc_zero(mem_ctx, union lsa_TrustedDomainInfo);
1431 if (!info) {
1432 return NT_STATUS_NO_MEMORY;
1434 *r->out.info = info;
1436 switch (r->in.level) {
1437 case LSA_TRUSTED_DOMAIN_INFO_NAME:
1438 info->name.netbios_name.string
1439 = samdb_result_string(msg, "flatname", NULL);
1440 break;
1441 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1442 info->posix_offset.posix_offset
1443 = samdb_result_uint(msg, "posixOffset", 0);
1444 break;
1445 #if 0 /* Win2k3 doesn't implement this */
1446 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
1447 r->out.info->info_basic.netbios_name.string
1448 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1449 r->out.info->info_basic.sid
1450 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1451 break;
1452 #endif
1453 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1454 return fill_trust_domain_ex(mem_ctx, msg, &info->info_ex);
1456 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1457 ZERO_STRUCT(info->full_info);
1458 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info.info_ex);
1460 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
1461 ZERO_STRUCT(info->full_info2_internal);
1462 info->full_info2_internal.posix_offset.posix_offset
1463 = samdb_result_uint(msg, "posixOffset", 0);
1464 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info2_internal.info.info_ex);
1466 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
1467 info->enc_types.enc_types
1468 = samdb_result_uint(msg, "msDs-supportedEncryptionTypes", KERB_ENCTYPE_RC4_HMAC_MD5);
1469 break;
1471 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
1472 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
1473 /* oops, we don't want to return the info after all */
1474 talloc_free(info);
1475 *r->out.info = NULL;
1476 return NT_STATUS_INVALID_PARAMETER;
1477 default:
1478 /* oops, we don't want to return the info after all */
1479 talloc_free(info);
1480 *r->out.info = NULL;
1481 return NT_STATUS_INVALID_INFO_CLASS;
1484 return NT_STATUS_OK;
1489 lsa_QueryTrustedDomainInfoBySid
1491 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1492 struct lsa_QueryTrustedDomainInfoBySid *r)
1494 NTSTATUS status;
1495 struct lsa_OpenTrustedDomain opn;
1496 struct lsa_QueryTrustedDomainInfo query;
1497 struct dcesrv_handle *h;
1499 opn.in.handle = r->in.handle;
1500 opn.in.sid = r->in.dom_sid;
1501 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1502 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1503 if (!opn.out.trustdom_handle) {
1504 return NT_STATUS_NO_MEMORY;
1506 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
1507 if (!NT_STATUS_IS_OK(status)) {
1508 return status;
1511 /* Ensure this handle goes away at the end of this call */
1512 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
1513 talloc_steal(mem_ctx, h);
1515 query.in.trustdom_handle = opn.out.trustdom_handle;
1516 query.in.level = r->in.level;
1517 query.out.info = r->out.info;
1518 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1519 if (!NT_STATUS_IS_OK(status)) {
1520 return status;
1523 return NT_STATUS_OK;
1527 lsa_SetTrustedDomainInfoByName
1529 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1530 TALLOC_CTX *mem_ctx,
1531 struct lsa_SetTrustedDomainInfoByName *r)
1533 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1537 lsa_QueryTrustedDomainInfoByName
1539 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1540 TALLOC_CTX *mem_ctx,
1541 struct lsa_QueryTrustedDomainInfoByName *r)
1543 NTSTATUS status;
1544 struct lsa_OpenTrustedDomainByName opn;
1545 struct lsa_QueryTrustedDomainInfo query;
1546 struct dcesrv_handle *h;
1548 opn.in.handle = r->in.handle;
1549 opn.in.name = *r->in.trusted_domain;
1550 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1551 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1552 if (!opn.out.trustdom_handle) {
1553 return NT_STATUS_NO_MEMORY;
1555 status = dcesrv_lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &opn);
1556 if (!NT_STATUS_IS_OK(status)) {
1557 return status;
1560 /* Ensure this handle goes away at the end of this call */
1561 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
1562 talloc_steal(mem_ctx, h);
1564 query.in.trustdom_handle = opn.out.trustdom_handle;
1565 query.in.level = r->in.level;
1566 query.out.info = r->out.info;
1567 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1568 if (!NT_STATUS_IS_OK(status)) {
1569 return status;
1572 return NT_STATUS_OK;
1576 lsa_CloseTrustedDomainEx
1578 static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
1579 TALLOC_CTX *mem_ctx,
1580 struct lsa_CloseTrustedDomainEx *r)
1582 /* The result of a bad hair day from an IDL programmer? Not
1583 * implmented in Win2k3. You should always just lsa_Close
1584 * anyway. */
1585 return NT_STATUS_NOT_IMPLEMENTED;
1590 comparison function for sorting lsa_DomainInformation array
1592 static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
1594 return strcasecmp_m(e1->name.string, e2->name.string);
1598 lsa_EnumTrustDom
1600 static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1601 struct lsa_EnumTrustDom *r)
1603 struct dcesrv_handle *policy_handle;
1604 struct lsa_DomainInfo *entries;
1605 struct lsa_policy_state *policy_state;
1606 struct ldb_message **domains;
1607 const char *attrs[] = {
1608 "flatname",
1609 "securityIdentifier",
1610 NULL
1614 int count, i;
1616 *r->out.resume_handle = 0;
1618 r->out.domains->domains = NULL;
1619 r->out.domains->count = 0;
1621 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1623 policy_state = policy_handle->data;
1625 /* search for all users in this domain. This could possibly be cached and
1626 resumed based on resume_key */
1627 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1628 "objectclass=trustedDomain");
1629 if (count < 0) {
1630 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1633 /* convert to lsa_TrustInformation format */
1634 entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
1635 if (!entries) {
1636 return NT_STATUS_NO_MEMORY;
1638 for (i=0;i<count;i++) {
1639 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
1640 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
1643 /* sort the results by name */
1644 TYPESAFE_QSORT(entries, count, compare_DomainInfo);
1646 if (*r->in.resume_handle >= count) {
1647 *r->out.resume_handle = -1;
1649 return NT_STATUS_NO_MORE_ENTRIES;
1652 /* return the rest, limit by max_size. Note that we
1653 use the w2k3 element size value of 60 */
1654 r->out.domains->count = count - *r->in.resume_handle;
1655 r->out.domains->count = MIN(r->out.domains->count,
1656 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
1658 r->out.domains->domains = entries + *r->in.resume_handle;
1659 r->out.domains->count = r->out.domains->count;
1661 if (r->out.domains->count < count - *r->in.resume_handle) {
1662 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1663 return STATUS_MORE_ENTRIES;
1666 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
1667 * always be larger than the previous input resume handle, in
1668 * particular when hitting the last query it is vital to set the
1669 * resume handle correctly to avoid infinite client loops, as
1670 * seen e.g. with Windows XP SP3 when resume handle is 0 and
1671 * status is NT_STATUS_OK - gd */
1673 *r->out.resume_handle = (uint32_t)-1;
1675 return NT_STATUS_OK;
1679 comparison function for sorting lsa_DomainInformation array
1681 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
1683 return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
1687 lsa_EnumTrustedDomainsEx
1689 static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1690 struct lsa_EnumTrustedDomainsEx *r)
1692 struct dcesrv_handle *policy_handle;
1693 struct lsa_TrustDomainInfoInfoEx *entries;
1694 struct lsa_policy_state *policy_state;
1695 struct ldb_message **domains;
1696 const char *attrs[] = {
1697 "flatname",
1698 "trustPartner",
1699 "securityIdentifier",
1700 "trustDirection",
1701 "trustType",
1702 "trustAttributes",
1703 NULL
1705 NTSTATUS nt_status;
1707 int count, i;
1709 *r->out.resume_handle = 0;
1711 r->out.domains->domains = NULL;
1712 r->out.domains->count = 0;
1714 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1716 policy_state = policy_handle->data;
1718 /* search for all users in this domain. This could possibly be cached and
1719 resumed based on resume_key */
1720 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1721 "objectclass=trustedDomain");
1722 if (count < 0) {
1723 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1726 /* convert to lsa_DomainInformation format */
1727 entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
1728 if (!entries) {
1729 return NT_STATUS_NO_MEMORY;
1731 for (i=0;i<count;i++) {
1732 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
1733 if (!NT_STATUS_IS_OK(nt_status)) {
1734 return nt_status;
1738 /* sort the results by name */
1739 TYPESAFE_QSORT(entries, count, compare_TrustDomainInfoInfoEx);
1741 if (*r->in.resume_handle >= count) {
1742 *r->out.resume_handle = -1;
1744 return NT_STATUS_NO_MORE_ENTRIES;
1747 /* return the rest, limit by max_size. Note that we
1748 use the w2k3 element size value of 60 */
1749 r->out.domains->count = count - *r->in.resume_handle;
1750 r->out.domains->count = MIN(r->out.domains->count,
1751 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
1753 r->out.domains->domains = entries + *r->in.resume_handle;
1754 r->out.domains->count = r->out.domains->count;
1756 if (r->out.domains->count < count - *r->in.resume_handle) {
1757 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1758 return STATUS_MORE_ENTRIES;
1761 return NT_STATUS_OK;
1766 lsa_OpenAccount
1768 static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1769 struct lsa_OpenAccount *r)
1771 struct dcesrv_handle *h, *ah;
1772 struct lsa_policy_state *state;
1773 struct lsa_account_state *astate;
1775 ZERO_STRUCTP(r->out.acct_handle);
1777 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1779 state = h->data;
1781 astate = talloc(dce_call->conn, struct lsa_account_state);
1782 if (astate == NULL) {
1783 return NT_STATUS_NO_MEMORY;
1786 astate->account_sid = dom_sid_dup(astate, r->in.sid);
1787 if (astate->account_sid == NULL) {
1788 talloc_free(astate);
1789 return NT_STATUS_NO_MEMORY;
1792 astate->policy = talloc_reference(astate, state);
1793 astate->access_mask = r->in.access_mask;
1795 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
1796 if (!ah) {
1797 talloc_free(astate);
1798 return NT_STATUS_NO_MEMORY;
1801 ah->data = talloc_steal(ah, astate);
1803 *r->out.acct_handle = ah->wire_handle;
1805 return NT_STATUS_OK;
1810 lsa_EnumPrivsAccount
1812 static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
1813 TALLOC_CTX *mem_ctx,
1814 struct lsa_EnumPrivsAccount *r)
1816 struct dcesrv_handle *h;
1817 struct lsa_account_state *astate;
1818 int ret;
1819 unsigned int i;
1820 struct ldb_message **res;
1821 const char * const attrs[] = { "privilege", NULL};
1822 struct ldb_message_element *el;
1823 const char *sidstr;
1824 struct lsa_PrivilegeSet *privs;
1826 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1828 astate = h->data;
1830 privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
1831 if (privs == NULL) {
1832 return NT_STATUS_NO_MEMORY;
1834 privs->count = 0;
1835 privs->unknown = 0;
1836 privs->set = NULL;
1838 *r->out.privs = privs;
1840 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
1841 if (sidstr == NULL) {
1842 return NT_STATUS_NO_MEMORY;
1845 ret = gendb_search(astate->policy->pdb, mem_ctx, NULL, &res, attrs,
1846 "objectSid=%s", sidstr);
1847 if (ret < 0) {
1848 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1850 if (ret != 1) {
1851 return NT_STATUS_OK;
1854 el = ldb_msg_find_element(res[0], "privilege");
1855 if (el == NULL || el->num_values == 0) {
1856 return NT_STATUS_OK;
1859 privs->set = talloc_array(privs,
1860 struct lsa_LUIDAttribute, el->num_values);
1861 if (privs->set == NULL) {
1862 return NT_STATUS_NO_MEMORY;
1865 for (i=0;i<el->num_values;i++) {
1866 int id = sec_privilege_id((const char *)el->values[i].data);
1867 if (id == -1) {
1868 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1870 privs->set[i].attribute = 0;
1871 privs->set[i].luid.low = id;
1872 privs->set[i].luid.high = 0;
1875 privs->count = el->num_values;
1877 return NT_STATUS_OK;
1881 lsa_EnumAccountRights
1883 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
1884 TALLOC_CTX *mem_ctx,
1885 struct lsa_EnumAccountRights *r)
1887 struct dcesrv_handle *h;
1888 struct lsa_policy_state *state;
1889 int ret;
1890 unsigned int i;
1891 struct ldb_message **res;
1892 const char * const attrs[] = { "privilege", NULL};
1893 const char *sidstr;
1894 struct ldb_message_element *el;
1896 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1898 state = h->data;
1900 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
1901 if (sidstr == NULL) {
1902 return NT_STATUS_NO_MEMORY;
1905 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
1906 "(&(objectSid=%s)(privilege=*))", sidstr);
1907 if (ret == 0) {
1908 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1910 if (ret != 1) {
1911 DEBUG(3, ("searching for account rights for SID: %s failed: %s",
1912 dom_sid_string(mem_ctx, r->in.sid),
1913 ldb_errstring(state->pdb)));
1914 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1917 el = ldb_msg_find_element(res[0], "privilege");
1918 if (el == NULL || el->num_values == 0) {
1919 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1922 r->out.rights->count = el->num_values;
1923 r->out.rights->names = talloc_array(r->out.rights,
1924 struct lsa_StringLarge, r->out.rights->count);
1925 if (r->out.rights->names == NULL) {
1926 return NT_STATUS_NO_MEMORY;
1929 for (i=0;i<el->num_values;i++) {
1930 r->out.rights->names[i].string = (const char *)el->values[i].data;
1933 return NT_STATUS_OK;
1939 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
1941 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
1942 TALLOC_CTX *mem_ctx,
1943 struct lsa_policy_state *state,
1944 int ldb_flag,
1945 struct dom_sid *sid,
1946 const struct lsa_RightSet *rights)
1948 const char *sidstr, *sidndrstr;
1949 struct ldb_message *msg;
1950 struct ldb_message_element *el;
1951 int ret;
1952 uint32_t i;
1953 struct lsa_EnumAccountRights r2;
1954 char *dnstr;
1956 if (security_session_user_level(dce_call->conn->auth_state.session_info) <
1957 SECURITY_ADMINISTRATOR) {
1958 DEBUG(0,("lsa_AddRemoveAccount refused for supplied security token\n"));
1959 return NT_STATUS_ACCESS_DENIED;
1962 msg = ldb_msg_new(mem_ctx);
1963 if (msg == NULL) {
1964 return NT_STATUS_NO_MEMORY;
1967 sidndrstr = ldap_encode_ndr_dom_sid(msg, sid);
1968 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidndrstr, msg);
1970 sidstr = dom_sid_string(msg, sid);
1971 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidstr, msg);
1973 dnstr = talloc_asprintf(msg, "sid=%s", sidstr);
1974 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(dnstr, msg);
1976 msg->dn = ldb_dn_new(msg, state->pdb, dnstr);
1977 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg->dn, msg);
1979 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1980 NTSTATUS status;
1982 r2.in.handle = &state->handle->wire_handle;
1983 r2.in.sid = sid;
1984 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
1986 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1987 if (!NT_STATUS_IS_OK(status)) {
1988 ZERO_STRUCTP(r2.out.rights);
1992 for (i=0;i<rights->count;i++) {
1993 if (sec_privilege_id(rights->names[i].string) == -1) {
1994 talloc_free(msg);
1995 return NT_STATUS_NO_SUCH_PRIVILEGE;
1998 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1999 uint32_t j;
2000 for (j=0;j<r2.out.rights->count;j++) {
2001 if (strcasecmp_m(r2.out.rights->names[j].string,
2002 rights->names[i].string) == 0) {
2003 break;
2006 if (j != r2.out.rights->count) continue;
2009 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
2010 if (ret != LDB_SUCCESS) {
2011 talloc_free(msg);
2012 return NT_STATUS_NO_MEMORY;
2016 el = ldb_msg_find_element(msg, "privilege");
2017 if (!el) {
2018 talloc_free(msg);
2019 return NT_STATUS_OK;
2022 el->flags = ldb_flag;
2024 ret = ldb_modify(state->pdb, msg);
2025 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
2026 if (samdb_msg_add_dom_sid(state->pdb, msg, msg, "objectSid", sid) != LDB_SUCCESS) {
2027 talloc_free(msg);
2028 return NT_STATUS_NO_MEMORY;
2030 samdb_msg_add_string(state->pdb, msg, msg, "comment", "added via LSA");
2031 ret = ldb_add(state->pdb, msg);
2033 if (ret != LDB_SUCCESS) {
2034 if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
2035 talloc_free(msg);
2036 return NT_STATUS_OK;
2038 DEBUG(3, ("Could not %s attributes from %s: %s",
2039 ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add",
2040 ldb_dn_get_linearized(msg->dn), ldb_errstring(state->pdb)));
2041 talloc_free(msg);
2042 return NT_STATUS_UNEXPECTED_IO_ERROR;
2045 talloc_free(msg);
2046 return NT_STATUS_OK;
2050 lsa_AddPrivilegesToAccount
2052 static NTSTATUS dcesrv_lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2053 struct lsa_AddPrivilegesToAccount *r)
2055 struct lsa_RightSet rights;
2056 struct dcesrv_handle *h;
2057 struct lsa_account_state *astate;
2058 uint32_t i;
2060 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2062 astate = h->data;
2064 rights.count = r->in.privs->count;
2065 rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
2066 if (rights.names == NULL) {
2067 return NT_STATUS_NO_MEMORY;
2069 for (i=0;i<rights.count;i++) {
2070 int id = r->in.privs->set[i].luid.low;
2071 if (r->in.privs->set[i].luid.high) {
2072 return NT_STATUS_NO_SUCH_PRIVILEGE;
2074 rights.names[i].string = sec_privilege_name(id);
2075 if (rights.names[i].string == NULL) {
2076 return NT_STATUS_NO_SUCH_PRIVILEGE;
2080 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2081 LDB_FLAG_MOD_ADD, astate->account_sid,
2082 &rights);
2087 lsa_RemovePrivilegesFromAccount
2089 static NTSTATUS dcesrv_lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2090 struct lsa_RemovePrivilegesFromAccount *r)
2092 struct lsa_RightSet *rights;
2093 struct dcesrv_handle *h;
2094 struct lsa_account_state *astate;
2095 uint32_t i;
2097 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2099 astate = h->data;
2101 rights = talloc(mem_ctx, struct lsa_RightSet);
2103 if (r->in.remove_all == 1 &&
2104 r->in.privs == NULL) {
2105 struct lsa_EnumAccountRights r2;
2106 NTSTATUS status;
2108 r2.in.handle = &astate->policy->handle->wire_handle;
2109 r2.in.sid = astate->account_sid;
2110 r2.out.rights = rights;
2112 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
2113 if (!NT_STATUS_IS_OK(status)) {
2114 return status;
2117 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2118 LDB_FLAG_MOD_DELETE, astate->account_sid,
2119 r2.out.rights);
2122 if (r->in.remove_all != 0) {
2123 return NT_STATUS_INVALID_PARAMETER;
2126 rights->count = r->in.privs->count;
2127 rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
2128 if (rights->names == NULL) {
2129 return NT_STATUS_NO_MEMORY;
2131 for (i=0;i<rights->count;i++) {
2132 int id = r->in.privs->set[i].luid.low;
2133 if (r->in.privs->set[i].luid.high) {
2134 return NT_STATUS_NO_SUCH_PRIVILEGE;
2136 rights->names[i].string = sec_privilege_name(id);
2137 if (rights->names[i].string == NULL) {
2138 return NT_STATUS_NO_SUCH_PRIVILEGE;
2142 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2143 LDB_FLAG_MOD_DELETE, astate->account_sid,
2144 rights);
2149 lsa_GetQuotasForAccount
2151 static NTSTATUS dcesrv_lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2152 struct lsa_GetQuotasForAccount *r)
2154 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2159 lsa_SetQuotasForAccount
2161 static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2162 struct lsa_SetQuotasForAccount *r)
2164 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2169 lsa_GetSystemAccessAccount
2171 static NTSTATUS dcesrv_lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2172 struct lsa_GetSystemAccessAccount *r)
2174 uint32_t i;
2175 NTSTATUS status;
2176 struct lsa_EnumPrivsAccount enumPrivs;
2177 struct lsa_PrivilegeSet *privs;
2179 privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
2180 if (!privs) {
2181 return NT_STATUS_NO_MEMORY;
2183 privs->count = 0;
2184 privs->unknown = 0;
2185 privs->set = NULL;
2187 enumPrivs.in.handle = r->in.handle;
2188 enumPrivs.out.privs = &privs;
2190 status = dcesrv_lsa_EnumPrivsAccount(dce_call, mem_ctx, &enumPrivs);
2191 if (!NT_STATUS_IS_OK(status)) {
2192 return status;
2195 *(r->out.access_mask) = 0x00000000;
2197 for (i = 0; i < privs->count; i++) {
2198 int priv = privs->set[i].luid.low;
2200 switch (priv) {
2201 case SEC_PRIV_INTERACTIVE_LOGON:
2202 *(r->out.access_mask) |= LSA_POLICY_MODE_INTERACTIVE;
2203 break;
2204 case SEC_PRIV_NETWORK_LOGON:
2205 *(r->out.access_mask) |= LSA_POLICY_MODE_NETWORK;
2206 break;
2207 case SEC_PRIV_REMOTE_INTERACTIVE_LOGON:
2208 *(r->out.access_mask) |= LSA_POLICY_MODE_REMOTE_INTERACTIVE;
2209 break;
2213 return NT_STATUS_OK;
2218 lsa_SetSystemAccessAccount
2220 static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2221 struct lsa_SetSystemAccessAccount *r)
2223 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2228 lsa_CreateSecret
2230 static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2231 struct lsa_CreateSecret *r)
2233 struct dcesrv_handle *policy_handle;
2234 struct lsa_policy_state *policy_state;
2235 struct lsa_secret_state *secret_state;
2236 struct dcesrv_handle *handle;
2237 struct ldb_message **msgs, *msg;
2238 const char *attrs[] = {
2239 NULL
2242 const char *name;
2244 int ret;
2246 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2247 ZERO_STRUCTP(r->out.sec_handle);
2249 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2251 case SECURITY_SYSTEM:
2252 case SECURITY_ADMINISTRATOR:
2253 break;
2254 default:
2255 /* Users and annonymous are not allowed create secrets */
2256 return NT_STATUS_ACCESS_DENIED;
2259 policy_state = policy_handle->data;
2261 if (!r->in.name.string) {
2262 return NT_STATUS_INVALID_PARAMETER;
2265 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2266 if (!secret_state) {
2267 return NT_STATUS_NO_MEMORY;
2269 secret_state->policy = policy_state;
2271 msg = ldb_msg_new(mem_ctx);
2272 if (msg == NULL) {
2273 return NT_STATUS_NO_MEMORY;
2276 if (strncmp("G$", r->in.name.string, 2) == 0) {
2277 const char *name2;
2278 name = &r->in.name.string[2];
2279 /* We need to connect to the database as system, as this is one of the rare RPC calls that must read the secrets (and this is denied otherwise) */
2280 secret_state->sam_ldb = talloc_reference(secret_state,
2281 samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(dce_call->conn->dce_ctx->lp_ctx)));
2282 secret_state->global = true;
2284 if (strlen(name) < 1) {
2285 return NT_STATUS_INVALID_PARAMETER;
2288 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
2289 /* search for the secret record */
2290 ret = gendb_search(secret_state->sam_ldb,
2291 mem_ctx, policy_state->system_dn, &msgs, attrs,
2292 "(&(cn=%s)(objectclass=secret))",
2293 name2);
2294 if (ret > 0) {
2295 return NT_STATUS_OBJECT_NAME_COLLISION;
2298 if (ret < 0) {
2299 DEBUG(0,("Failure searching for CN=%s: %s\n",
2300 name2, ldb_errstring(secret_state->sam_ldb)));
2301 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2304 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
2305 if (!name2 || ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
2306 return NT_STATUS_NO_MEMORY;
2309 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
2311 } else {
2312 secret_state->global = false;
2314 name = r->in.name.string;
2315 if (strlen(name) < 1) {
2316 return NT_STATUS_INVALID_PARAMETER;
2319 secret_state->sam_ldb = talloc_reference(secret_state,
2320 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
2321 /* search for the secret record */
2322 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2323 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2324 &msgs, attrs,
2325 "(&(cn=%s)(objectclass=secret))",
2326 ldb_binary_encode_string(mem_ctx, name));
2327 if (ret > 0) {
2328 return NT_STATUS_OBJECT_NAME_COLLISION;
2331 if (ret < 0) {
2332 DEBUG(0,("Failure searching for CN=%s: %s\n",
2333 name, ldb_errstring(secret_state->sam_ldb)));
2334 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2337 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name);
2338 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
2341 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
2343 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
2345 /* create the secret */
2346 ret = ldb_add(secret_state->sam_ldb, msg);
2347 if (ret != LDB_SUCCESS) {
2348 DEBUG(0,("Failed to create secret record %s: %s\n",
2349 ldb_dn_get_linearized(msg->dn),
2350 ldb_errstring(secret_state->sam_ldb)));
2351 return NT_STATUS_ACCESS_DENIED;
2354 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2355 if (!handle) {
2356 return NT_STATUS_NO_MEMORY;
2359 handle->data = talloc_steal(handle, secret_state);
2361 secret_state->access_mask = r->in.access_mask;
2362 secret_state->policy = talloc_reference(secret_state, policy_state);
2364 *r->out.sec_handle = handle->wire_handle;
2366 return NT_STATUS_OK;
2371 lsa_OpenSecret
2373 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2374 struct lsa_OpenSecret *r)
2376 struct dcesrv_handle *policy_handle;
2378 struct lsa_policy_state *policy_state;
2379 struct lsa_secret_state *secret_state;
2380 struct dcesrv_handle *handle;
2381 struct ldb_message **msgs;
2382 const char *attrs[] = {
2383 NULL
2386 const char *name;
2388 int ret;
2390 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2391 ZERO_STRUCTP(r->out.sec_handle);
2392 policy_state = policy_handle->data;
2394 if (!r->in.name.string) {
2395 return NT_STATUS_INVALID_PARAMETER;
2398 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2400 case SECURITY_SYSTEM:
2401 case SECURITY_ADMINISTRATOR:
2402 break;
2403 default:
2404 /* Users and annonymous are not allowed to access secrets */
2405 return NT_STATUS_ACCESS_DENIED;
2408 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2409 if (!secret_state) {
2410 return NT_STATUS_NO_MEMORY;
2412 secret_state->policy = policy_state;
2414 if (strncmp("G$", r->in.name.string, 2) == 0) {
2415 name = &r->in.name.string[2];
2416 /* We need to connect to the database as system, as this is one of the rare RPC calls that must read the secrets (and this is denied otherwise) */
2417 secret_state->sam_ldb = talloc_reference(secret_state,
2418 samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(dce_call->conn->dce_ctx->lp_ctx)));
2419 secret_state->global = true;
2421 if (strlen(name) < 1) {
2422 return NT_STATUS_INVALID_PARAMETER;
2425 /* search for the secret record */
2426 ret = gendb_search(secret_state->sam_ldb,
2427 mem_ctx, policy_state->system_dn, &msgs, attrs,
2428 "(&(cn=%s Secret)(objectclass=secret))",
2429 ldb_binary_encode_string(mem_ctx, name));
2430 if (ret == 0) {
2431 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2434 if (ret != 1) {
2435 DEBUG(0,("Found %d records matching DN %s\n", ret,
2436 ldb_dn_get_linearized(policy_state->system_dn)));
2437 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2440 } else {
2441 secret_state->global = false;
2442 secret_state->sam_ldb = talloc_reference(secret_state,
2443 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
2445 name = r->in.name.string;
2446 if (strlen(name) < 1) {
2447 return NT_STATUS_INVALID_PARAMETER;
2450 /* search for the secret record */
2451 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2452 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2453 &msgs, attrs,
2454 "(&(cn=%s)(objectclass=secret))",
2455 ldb_binary_encode_string(mem_ctx, name));
2456 if (ret == 0) {
2457 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2460 if (ret != 1) {
2461 DEBUG(0,("Found %d records matching CN=%s\n",
2462 ret, ldb_binary_encode_string(mem_ctx, name)));
2463 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2467 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
2469 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2470 if (!handle) {
2471 return NT_STATUS_NO_MEMORY;
2474 handle->data = talloc_steal(handle, secret_state);
2476 secret_state->access_mask = r->in.access_mask;
2477 secret_state->policy = talloc_reference(secret_state, policy_state);
2479 *r->out.sec_handle = handle->wire_handle;
2481 return NT_STATUS_OK;
2486 lsa_SetSecret
2488 static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2489 struct lsa_SetSecret *r)
2492 struct dcesrv_handle *h;
2493 struct lsa_secret_state *secret_state;
2494 struct ldb_message *msg;
2495 DATA_BLOB session_key;
2496 DATA_BLOB crypt_secret, secret;
2497 struct ldb_val val;
2498 int ret;
2499 NTSTATUS status = NT_STATUS_OK;
2501 struct timeval now = timeval_current();
2502 NTTIME nt_now = timeval_to_nttime(&now);
2504 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2506 secret_state = h->data;
2508 msg = ldb_msg_new(mem_ctx);
2509 if (msg == NULL) {
2510 return NT_STATUS_NO_MEMORY;
2513 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
2514 if (!msg->dn) {
2515 return NT_STATUS_NO_MEMORY;
2517 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2518 if (!NT_STATUS_IS_OK(status)) {
2519 return status;
2522 if (r->in.old_val) {
2523 /* Decrypt */
2524 crypt_secret.data = r->in.old_val->data;
2525 crypt_secret.length = r->in.old_val->size;
2527 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2528 if (!NT_STATUS_IS_OK(status)) {
2529 return status;
2532 val.data = secret.data;
2533 val.length = secret.length;
2535 /* set value */
2536 if (samdb_msg_add_value(secret_state->sam_ldb,
2537 mem_ctx, msg, "priorValue", &val) != LDB_SUCCESS) {
2538 return NT_STATUS_NO_MEMORY;
2541 /* set old value mtime */
2542 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2543 mem_ctx, msg, "priorSetTime", nt_now) != LDB_SUCCESS) {
2544 return NT_STATUS_NO_MEMORY;
2547 } else {
2548 /* If the old value is not set, then migrate the
2549 * current value to the old value */
2550 const struct ldb_val *old_val;
2551 NTTIME last_set_time;
2552 struct ldb_message **res;
2553 const char *attrs[] = {
2554 "currentValue",
2555 "lastSetTime",
2556 NULL
2559 /* search for the secret record */
2560 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
2561 secret_state->secret_dn, &res, attrs);
2562 if (ret == 0) {
2563 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2566 if (ret != 1) {
2567 DEBUG(0,("Found %d records matching dn=%s\n", ret,
2568 ldb_dn_get_linearized(secret_state->secret_dn)));
2569 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2572 old_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2573 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2575 if (old_val) {
2576 /* set old value */
2577 if (samdb_msg_add_value(secret_state->sam_ldb,
2578 mem_ctx, msg, "priorValue",
2579 old_val) != 0) {
2580 return NT_STATUS_NO_MEMORY;
2582 } else {
2583 if (samdb_msg_add_delete(secret_state->sam_ldb,
2584 mem_ctx, msg, "priorValue")) {
2585 return NT_STATUS_NO_MEMORY;
2590 /* set old value mtime */
2591 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2592 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2593 mem_ctx, msg, "priorSetTime", last_set_time) != LDB_SUCCESS) {
2594 return NT_STATUS_NO_MEMORY;
2596 } else {
2597 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2598 mem_ctx, msg, "priorSetTime", nt_now) != LDB_SUCCESS) {
2599 return NT_STATUS_NO_MEMORY;
2604 if (r->in.new_val) {
2605 /* Decrypt */
2606 crypt_secret.data = r->in.new_val->data;
2607 crypt_secret.length = r->in.new_val->size;
2609 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2610 if (!NT_STATUS_IS_OK(status)) {
2611 return status;
2614 val.data = secret.data;
2615 val.length = secret.length;
2617 /* set value */
2618 if (samdb_msg_add_value(secret_state->sam_ldb,
2619 mem_ctx, msg, "currentValue", &val) != LDB_SUCCESS) {
2620 return NT_STATUS_NO_MEMORY;
2623 /* set new value mtime */
2624 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2625 mem_ctx, msg, "lastSetTime", nt_now) != LDB_SUCCESS) {
2626 return NT_STATUS_NO_MEMORY;
2629 } else {
2630 /* NULL out the NEW value */
2631 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2632 mem_ctx, msg, "lastSetTime", nt_now) != LDB_SUCCESS) {
2633 return NT_STATUS_NO_MEMORY;
2635 if (samdb_msg_add_delete(secret_state->sam_ldb,
2636 mem_ctx, msg, "currentValue") != LDB_SUCCESS) {
2637 return NT_STATUS_NO_MEMORY;
2641 /* modify the samdb record */
2642 ret = dsdb_replace(secret_state->sam_ldb, msg, 0);
2643 if (ret != LDB_SUCCESS) {
2644 /* we really need samdb.c to return NTSTATUS */
2645 return NT_STATUS_UNSUCCESSFUL;
2648 return NT_STATUS_OK;
2653 lsa_QuerySecret
2655 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2656 struct lsa_QuerySecret *r)
2658 struct dcesrv_handle *h;
2659 struct lsa_secret_state *secret_state;
2660 struct ldb_message *msg;
2661 DATA_BLOB session_key;
2662 DATA_BLOB crypt_secret, secret;
2663 int ret;
2664 struct ldb_message **res;
2665 const char *attrs[] = {
2666 "currentValue",
2667 "priorValue",
2668 "lastSetTime",
2669 "priorSetTime",
2670 NULL
2673 NTSTATUS nt_status;
2675 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2677 /* Ensure user is permitted to read this... */
2678 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2680 case SECURITY_SYSTEM:
2681 case SECURITY_ADMINISTRATOR:
2682 break;
2683 default:
2684 /* Users and annonymous are not allowed to read secrets */
2685 return NT_STATUS_ACCESS_DENIED;
2688 secret_state = h->data;
2690 /* pull all the user attributes */
2691 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2692 secret_state->secret_dn, &res, attrs);
2693 if (ret != 1) {
2694 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2696 msg = res[0];
2698 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2699 if (!NT_STATUS_IS_OK(nt_status)) {
2700 return nt_status;
2703 if (r->in.old_val) {
2704 const struct ldb_val *prior_val;
2705 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2706 if (!r->out.old_val) {
2707 return NT_STATUS_NO_MEMORY;
2709 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
2711 if (prior_val && prior_val->length) {
2712 secret.data = prior_val->data;
2713 secret.length = prior_val->length;
2715 /* Encrypt */
2716 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2717 if (!crypt_secret.length) {
2718 return NT_STATUS_NO_MEMORY;
2720 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2721 if (!r->out.old_val->buf) {
2722 return NT_STATUS_NO_MEMORY;
2724 r->out.old_val->buf->size = crypt_secret.length;
2725 r->out.old_val->buf->length = crypt_secret.length;
2726 r->out.old_val->buf->data = crypt_secret.data;
2730 if (r->in.old_mtime) {
2731 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2732 if (!r->out.old_mtime) {
2733 return NT_STATUS_NO_MEMORY;
2735 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
2738 if (r->in.new_val) {
2739 const struct ldb_val *new_val;
2740 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2741 if (!r->out.new_val) {
2742 return NT_STATUS_NO_MEMORY;
2745 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2747 if (new_val && new_val->length) {
2748 secret.data = new_val->data;
2749 secret.length = new_val->length;
2751 /* Encrypt */
2752 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2753 if (!crypt_secret.length) {
2754 return NT_STATUS_NO_MEMORY;
2756 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2757 if (!r->out.new_val->buf) {
2758 return NT_STATUS_NO_MEMORY;
2760 r->out.new_val->buf->length = crypt_secret.length;
2761 r->out.new_val->buf->size = crypt_secret.length;
2762 r->out.new_val->buf->data = crypt_secret.data;
2766 if (r->in.new_mtime) {
2767 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2768 if (!r->out.new_mtime) {
2769 return NT_STATUS_NO_MEMORY;
2771 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2774 return NT_STATUS_OK;
2779 lsa_LookupPrivValue
2781 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
2782 TALLOC_CTX *mem_ctx,
2783 struct lsa_LookupPrivValue *r)
2785 struct dcesrv_handle *h;
2786 struct lsa_policy_state *state;
2787 int id;
2789 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2791 state = h->data;
2793 id = sec_privilege_id(r->in.name->string);
2794 if (id == -1) {
2795 return NT_STATUS_NO_SUCH_PRIVILEGE;
2798 r->out.luid->low = id;
2799 r->out.luid->high = 0;
2801 return NT_STATUS_OK;
2806 lsa_LookupPrivName
2808 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
2809 TALLOC_CTX *mem_ctx,
2810 struct lsa_LookupPrivName *r)
2812 struct dcesrv_handle *h;
2813 struct lsa_policy_state *state;
2814 struct lsa_StringLarge *name;
2815 const char *privname;
2817 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2819 state = h->data;
2821 if (r->in.luid->high != 0) {
2822 return NT_STATUS_NO_SUCH_PRIVILEGE;
2825 privname = sec_privilege_name(r->in.luid->low);
2826 if (privname == NULL) {
2827 return NT_STATUS_NO_SUCH_PRIVILEGE;
2830 name = talloc(mem_ctx, struct lsa_StringLarge);
2831 if (name == NULL) {
2832 return NT_STATUS_NO_MEMORY;
2835 name->string = privname;
2837 *r->out.name = name;
2839 return NT_STATUS_OK;
2844 lsa_LookupPrivDisplayName
2846 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
2847 TALLOC_CTX *mem_ctx,
2848 struct lsa_LookupPrivDisplayName *r)
2850 struct dcesrv_handle *h;
2851 struct lsa_policy_state *state;
2852 struct lsa_StringLarge *disp_name = NULL;
2853 int id;
2855 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2857 state = h->data;
2859 id = sec_privilege_id(r->in.name->string);
2860 if (id == -1) {
2861 return NT_STATUS_NO_SUCH_PRIVILEGE;
2864 disp_name = talloc(mem_ctx, struct lsa_StringLarge);
2865 if (disp_name == NULL) {
2866 return NT_STATUS_NO_MEMORY;
2869 disp_name->string = sec_privilege_display_name(id, &r->in.language_id);
2870 if (disp_name->string == NULL) {
2871 return NT_STATUS_INTERNAL_ERROR;
2874 *r->out.disp_name = disp_name;
2875 *r->out.returned_language_id = 0;
2877 return NT_STATUS_OK;
2882 lsa_EnumAccountsWithUserRight
2884 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
2885 TALLOC_CTX *mem_ctx,
2886 struct lsa_EnumAccountsWithUserRight *r)
2888 struct dcesrv_handle *h;
2889 struct lsa_policy_state *state;
2890 int ret, i;
2891 struct ldb_message **res;
2892 const char * const attrs[] = { "objectSid", NULL};
2893 const char *privname;
2895 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2897 state = h->data;
2899 if (r->in.name == NULL) {
2900 return NT_STATUS_NO_SUCH_PRIVILEGE;
2903 privname = r->in.name->string;
2904 if (sec_privilege_id(privname) == -1) {
2905 return NT_STATUS_NO_SUCH_PRIVILEGE;
2908 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
2909 "privilege=%s", privname);
2910 if (ret < 0) {
2911 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2913 if (ret == 0) {
2914 return NT_STATUS_NO_MORE_ENTRIES;
2917 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2918 if (r->out.sids->sids == NULL) {
2919 return NT_STATUS_NO_MEMORY;
2921 for (i=0;i<ret;i++) {
2922 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2923 res[i], "objectSid");
2924 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2926 r->out.sids->num_sids = ret;
2928 return NT_STATUS_OK;
2933 lsa_AddAccountRights
2935 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
2936 TALLOC_CTX *mem_ctx,
2937 struct lsa_AddAccountRights *r)
2939 struct dcesrv_handle *h;
2940 struct lsa_policy_state *state;
2942 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2944 state = h->data;
2946 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2947 LDB_FLAG_MOD_ADD,
2948 r->in.sid, r->in.rights);
2953 lsa_RemoveAccountRights
2955 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
2956 TALLOC_CTX *mem_ctx,
2957 struct lsa_RemoveAccountRights *r)
2959 struct dcesrv_handle *h;
2960 struct lsa_policy_state *state;
2962 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2964 state = h->data;
2966 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2967 LDB_FLAG_MOD_DELETE,
2968 r->in.sid, r->in.rights);
2973 lsa_StorePrivateData
2975 static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2976 struct lsa_StorePrivateData *r)
2978 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2983 lsa_RetrievePrivateData
2985 static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2986 struct lsa_RetrievePrivateData *r)
2988 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2993 lsa_GetUserName
2995 static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2996 struct lsa_GetUserName *r)
2998 NTSTATUS status = NT_STATUS_OK;
2999 const char *account_name;
3000 const char *authority_name;
3001 struct lsa_String *_account_name;
3002 struct lsa_String *_authority_name = NULL;
3004 /* this is what w2k3 does */
3005 r->out.account_name = r->in.account_name;
3006 r->out.authority_name = r->in.authority_name;
3008 if (r->in.account_name
3009 && *r->in.account_name
3010 /* && *(*r->in.account_name)->string */
3012 return NT_STATUS_INVALID_PARAMETER;
3015 if (r->in.authority_name
3016 && *r->in.authority_name
3017 /* && *(*r->in.authority_name)->string */
3019 return NT_STATUS_INVALID_PARAMETER;
3022 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
3023 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
3025 _account_name = talloc(mem_ctx, struct lsa_String);
3026 NT_STATUS_HAVE_NO_MEMORY(_account_name);
3027 _account_name->string = account_name;
3029 if (r->in.authority_name) {
3030 _authority_name = talloc(mem_ctx, struct lsa_String);
3031 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
3032 _authority_name->string = authority_name;
3035 *r->out.account_name = _account_name;
3036 if (r->out.authority_name) {
3037 *r->out.authority_name = _authority_name;
3040 return status;
3044 lsa_SetInfoPolicy2
3046 static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
3047 TALLOC_CTX *mem_ctx,
3048 struct lsa_SetInfoPolicy2 *r)
3050 /* need to support these */
3051 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3055 lsa_QueryDomainInformationPolicy
3057 static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
3058 TALLOC_CTX *mem_ctx,
3059 struct lsa_QueryDomainInformationPolicy *r)
3061 union lsa_DomainInformationPolicy *info;
3063 info = talloc(r->out.info, union lsa_DomainInformationPolicy);
3064 if (!info) {
3065 return NT_STATUS_NO_MEMORY;
3068 switch (r->in.level) {
3069 case LSA_DOMAIN_INFO_POLICY_EFS:
3070 talloc_free(info);
3071 *r->out.info = NULL;
3072 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3073 case LSA_DOMAIN_INFO_POLICY_KERBEROS:
3075 struct lsa_DomainInfoKerberos *k = &info->kerberos_info;
3076 struct smb_krb5_context *smb_krb5_context;
3077 int ret = smb_krb5_init_context(mem_ctx,
3078 dce_call->event_ctx,
3079 dce_call->conn->dce_ctx->lp_ctx,
3080 &smb_krb5_context);
3081 if (ret != 0) {
3082 talloc_free(info);
3083 *r->out.info = NULL;
3084 return NT_STATUS_INTERNAL_ERROR;
3086 k->enforce_restrictions = 0; /* FIXME, details missing from MS-LSAD 2.2.53 */
3087 k->service_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
3088 k->user_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
3089 k->user_tkt_renewaltime = 0; /* Need to find somewhere to store this, and query in KDC too */
3090 k->clock_skew = krb5_get_max_time_skew(smb_krb5_context->krb5_context);
3091 talloc_free(smb_krb5_context);
3092 *r->out.info = info;
3093 return NT_STATUS_OK;
3095 default:
3096 talloc_free(info);
3097 *r->out.info = NULL;
3098 return NT_STATUS_INVALID_INFO_CLASS;
3103 lsa_SetDomInfoPolicy
3105 static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
3106 TALLOC_CTX *mem_ctx,
3107 struct lsa_SetDomainInformationPolicy *r)
3109 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3113 lsa_TestCall
3115 static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
3116 TALLOC_CTX *mem_ctx,
3117 struct lsa_TestCall *r)
3119 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3123 lsa_CREDRWRITE
3125 static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3126 struct lsa_CREDRWRITE *r)
3128 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3133 lsa_CREDRREAD
3135 static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3136 struct lsa_CREDRREAD *r)
3138 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3143 lsa_CREDRENUMERATE
3145 static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3146 struct lsa_CREDRENUMERATE *r)
3148 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3153 lsa_CREDRWRITEDOMAINCREDENTIALS
3155 static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3156 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3158 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3163 lsa_CREDRREADDOMAINCREDENTIALS
3165 static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3166 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3168 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3173 lsa_CREDRDELETE
3175 static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3176 struct lsa_CREDRDELETE *r)
3178 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3183 lsa_CREDRGETTARGETINFO
3185 static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3186 struct lsa_CREDRGETTARGETINFO *r)
3188 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3193 lsa_CREDRPROFILELOADED
3195 static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3196 struct lsa_CREDRPROFILELOADED *r)
3198 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3203 lsa_CREDRGETSESSIONTYPES
3205 static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3206 struct lsa_CREDRGETSESSIONTYPES *r)
3208 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3213 lsa_LSARREGISTERAUDITEVENT
3215 static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3216 struct lsa_LSARREGISTERAUDITEVENT *r)
3218 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3223 lsa_LSARGENAUDITEVENT
3225 static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3226 struct lsa_LSARGENAUDITEVENT *r)
3228 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3233 lsa_LSARUNREGISTERAUDITEVENT
3235 static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3236 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3238 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3243 lsa_lsaRQueryForestTrustInformation
3245 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3246 struct lsa_lsaRQueryForestTrustInformation *r)
3248 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3253 lsa_LSARSETFORESTTRUSTINFORMATION
3255 static NTSTATUS dcesrv_lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3256 struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
3258 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3263 lsa_CREDRRENAME
3265 static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3266 struct lsa_CREDRRENAME *r)
3268 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3274 lsa_LSAROPENPOLICYSCE
3276 static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3277 struct lsa_LSAROPENPOLICYSCE *r)
3279 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3284 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
3286 static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3287 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
3289 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3294 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
3296 static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3297 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
3299 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3304 lsa_LSARADTREPORTSECURITYEVENT
3306 static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3307 struct lsa_LSARADTREPORTSECURITYEVENT *r)
3309 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3313 /* include the generated boilerplate */
3314 #include "librpc/gen_ndr/ndr_lsa_s.c"
3318 /*****************************************
3319 NOTE! The remaining calls below were
3320 removed in w2k3, so the DCESRV_FAULT()
3321 replies are the correct implementation. Do
3322 not try and fill these in with anything else
3323 ******************************************/
3326 dssetup_DsRoleDnsNameToFlatName
3328 static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3329 struct dssetup_DsRoleDnsNameToFlatName *r)
3331 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3336 dssetup_DsRoleDcAsDc
3338 static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3339 struct dssetup_DsRoleDcAsDc *r)
3341 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3346 dssetup_DsRoleDcAsReplica
3348 static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3349 struct dssetup_DsRoleDcAsReplica *r)
3351 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3356 dssetup_DsRoleDemoteDc
3358 static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3359 struct dssetup_DsRoleDemoteDc *r)
3361 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3366 dssetup_DsRoleGetDcOperationProgress
3368 static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3369 struct dssetup_DsRoleGetDcOperationProgress *r)
3371 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3376 dssetup_DsRoleGetDcOperationResults
3378 static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3379 struct dssetup_DsRoleGetDcOperationResults *r)
3381 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3386 dssetup_DsRoleCancel
3388 static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3389 struct dssetup_DsRoleCancel *r)
3391 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3396 dssetup_DsRoleServerSaveStateForUpgrade
3398 static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3399 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
3401 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3406 dssetup_DsRoleUpgradeDownlevelServer
3408 static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3409 struct dssetup_DsRoleUpgradeDownlevelServer *r)
3411 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3416 dssetup_DsRoleAbortDownlevelServerUpgrade
3418 static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3419 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
3421 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3425 /* include the generated boilerplate */
3426 #include "librpc/gen_ndr/ndr_dssetup_s.c"
3428 NTSTATUS dcerpc_server_lsa_init(void)
3430 NTSTATUS ret;
3432 ret = dcerpc_server_dssetup_init();
3433 if (!NT_STATUS_IS_OK(ret)) {
3434 return ret;
3436 ret = dcerpc_server_lsarpc_init();
3437 if (!NT_STATUS_IS_OK(ret)) {
3438 return ret;
3440 return ret;