s3/docs: Remove reference to nonexistent file.
[Samba/gbeck.git] / source4 / rpc_server / lsa / dcesrv_lsa.c
blob35e5d0f8ed0805eb5848631612b3432b2595442b
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"
33 this type allows us to distinguish handle types
37 state associated with a lsa_OpenAccount() operation
39 struct lsa_account_state {
40 struct lsa_policy_state *policy;
41 uint32_t access_mask;
42 struct dom_sid *account_sid;
47 state associated with a lsa_OpenSecret() operation
49 struct lsa_secret_state {
50 struct lsa_policy_state *policy;
51 uint32_t access_mask;
52 struct ldb_dn *secret_dn;
53 struct ldb_context *sam_ldb;
54 bool global;
58 state associated with a lsa_OpenTrustedDomain() operation
60 struct lsa_trusted_domain_state {
61 struct lsa_policy_state *policy;
62 uint32_t access_mask;
63 struct ldb_dn *trusted_domain_dn;
64 struct ldb_dn *trusted_domain_user_dn;
68 this is based on the samba3 function make_lsa_object_sd()
69 It uses the same logic, but with samba4 helper functions
71 static NTSTATUS dcesrv_build_lsa_sd(TALLOC_CTX *mem_ctx,
72 struct security_descriptor **sd,
73 struct dom_sid *sid,
74 uint32_t sid_access)
76 NTSTATUS status;
77 uint32_t rid;
78 struct dom_sid *domain_sid, *domain_admins_sid;
79 const char *domain_admins_sid_str, *sidstr;
80 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
82 status = dom_sid_split_rid(tmp_ctx, sid, &domain_sid, &rid);
83 NT_STATUS_NOT_OK_RETURN_AND_FREE(status, tmp_ctx);
85 domain_admins_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ADMINS);
86 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(domain_admins_sid, tmp_ctx);
88 domain_admins_sid_str = dom_sid_string(tmp_ctx, domain_admins_sid);
89 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(domain_admins_sid_str, tmp_ctx);
91 sidstr = dom_sid_string(tmp_ctx, sid);
92 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidstr, tmp_ctx);
94 *sd = security_descriptor_dacl_create(mem_ctx,
95 0, sidstr, NULL,
97 SID_WORLD,
98 SEC_ACE_TYPE_ACCESS_ALLOWED,
99 SEC_GENERIC_EXECUTE | SEC_GENERIC_READ, 0,
101 SID_BUILTIN_ADMINISTRATORS,
102 SEC_ACE_TYPE_ACCESS_ALLOWED,
103 SEC_GENERIC_ALL, 0,
105 SID_BUILTIN_ACCOUNT_OPERATORS,
106 SEC_ACE_TYPE_ACCESS_ALLOWED,
107 SEC_GENERIC_ALL, 0,
109 domain_admins_sid_str,
110 SEC_ACE_TYPE_ACCESS_ALLOWED,
111 SEC_GENERIC_ALL, 0,
113 sidstr,
114 SEC_ACE_TYPE_ACCESS_ALLOWED,
115 sid_access, 0,
117 NULL);
118 talloc_free(tmp_ctx);
120 NT_STATUS_HAVE_NO_MEMORY(*sd);
122 return NT_STATUS_OK;
126 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
127 TALLOC_CTX *mem_ctx,
128 struct lsa_EnumAccountRights *r);
130 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
131 TALLOC_CTX *mem_ctx,
132 struct lsa_policy_state *state,
133 int ldb_flag,
134 struct dom_sid *sid,
135 const struct lsa_RightSet *rights);
138 lsa_Close
140 static NTSTATUS dcesrv_lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
141 struct lsa_Close *r)
143 struct dcesrv_handle *h;
145 *r->out.handle = *r->in.handle;
147 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
149 talloc_free(h);
151 ZERO_STRUCTP(r->out.handle);
153 return NT_STATUS_OK;
158 lsa_Delete
160 static NTSTATUS dcesrv_lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
161 struct lsa_Delete *r)
163 return NT_STATUS_NOT_SUPPORTED;
168 lsa_DeleteObject
170 static NTSTATUS dcesrv_lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
171 struct lsa_DeleteObject *r)
173 struct dcesrv_handle *h;
174 int ret;
176 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
178 if (h->wire_handle.handle_type == LSA_HANDLE_SECRET) {
179 struct lsa_secret_state *secret_state = h->data;
181 /* Ensure user is permitted to delete this... */
182 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
184 case SECURITY_SYSTEM:
185 case SECURITY_ADMINISTRATOR:
186 break;
187 default:
188 /* Users and annonymous are not allowed delete things */
189 return NT_STATUS_ACCESS_DENIED;
192 ret = ldb_delete(secret_state->sam_ldb,
193 secret_state->secret_dn);
194 talloc_free(h);
195 if (ret != 0) {
196 return NT_STATUS_INVALID_HANDLE;
199 ZERO_STRUCTP(r->out.handle);
201 return NT_STATUS_OK;
202 } else if (h->wire_handle.handle_type == LSA_HANDLE_TRUSTED_DOMAIN) {
203 struct lsa_trusted_domain_state *trusted_domain_state =
204 talloc_get_type(h->data, struct lsa_trusted_domain_state);
205 ret = ldb_transaction_start(trusted_domain_state->policy->sam_ldb);
206 if (ret != 0) {
207 return NT_STATUS_INTERNAL_DB_CORRUPTION;
210 ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
211 trusted_domain_state->trusted_domain_dn);
212 if (ret != 0) {
213 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
214 return NT_STATUS_INVALID_HANDLE;
217 if (trusted_domain_state->trusted_domain_user_dn) {
218 ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
219 trusted_domain_state->trusted_domain_user_dn);
220 if (ret != 0) {
221 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
222 return NT_STATUS_INVALID_HANDLE;
226 ret = ldb_transaction_commit(trusted_domain_state->policy->sam_ldb);
227 if (ret != 0) {
228 return NT_STATUS_INTERNAL_DB_CORRUPTION;
230 talloc_free(h);
231 ZERO_STRUCTP(r->out.handle);
233 return NT_STATUS_OK;
234 } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
235 struct lsa_RightSet *rights;
236 struct lsa_account_state *astate;
237 struct lsa_EnumAccountRights r2;
238 NTSTATUS status;
240 rights = talloc(mem_ctx, struct lsa_RightSet);
242 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
244 astate = h->data;
246 r2.in.handle = &astate->policy->handle->wire_handle;
247 r2.in.sid = astate->account_sid;
248 r2.out.rights = rights;
250 /* dcesrv_lsa_EnumAccountRights takes a LSA_HANDLE_POLICY,
251 but we have a LSA_HANDLE_ACCOUNT here, so this call
252 will always fail */
253 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
254 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
255 return NT_STATUS_OK;
258 if (!NT_STATUS_IS_OK(status)) {
259 return status;
262 status = dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
263 LDB_FLAG_MOD_DELETE, astate->account_sid,
264 r2.out.rights);
265 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
266 return NT_STATUS_OK;
269 if (!NT_STATUS_IS_OK(status)) {
270 return status;
273 ZERO_STRUCTP(r->out.handle);
276 return NT_STATUS_INVALID_HANDLE;
281 lsa_EnumPrivs
283 static NTSTATUS dcesrv_lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
284 struct lsa_EnumPrivs *r)
286 struct dcesrv_handle *h;
287 struct lsa_policy_state *state;
288 int i;
289 const char *privname;
291 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
293 state = h->data;
295 i = *r->in.resume_handle;
296 if (i == 0) i = 1;
298 while ((privname = sec_privilege_name(i)) &&
299 r->out.privs->count < r->in.max_count) {
300 struct lsa_PrivEntry *e;
302 r->out.privs->privs = talloc_realloc(r->out.privs,
303 r->out.privs->privs,
304 struct lsa_PrivEntry,
305 r->out.privs->count+1);
306 if (r->out.privs->privs == NULL) {
307 return NT_STATUS_NO_MEMORY;
309 e = &r->out.privs->privs[r->out.privs->count];
310 e->luid.low = i;
311 e->luid.high = 0;
312 e->name.string = privname;
313 r->out.privs->count++;
314 i++;
317 *r->out.resume_handle = i;
319 return NT_STATUS_OK;
324 lsa_QuerySecObj
326 static NTSTATUS dcesrv_lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
327 struct lsa_QuerySecurity *r)
329 struct dcesrv_handle *h;
330 struct security_descriptor *sd;
331 NTSTATUS status;
332 struct dom_sid *sid;
334 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
336 sid = dce_call->conn->auth_state.session_info->security_token->user_sid;
338 if (h->wire_handle.handle_type == LSA_HANDLE_POLICY) {
339 status = dcesrv_build_lsa_sd(mem_ctx, &sd, sid, 0);
340 } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
341 status = dcesrv_build_lsa_sd(mem_ctx, &sd, sid,
342 LSA_ACCOUNT_ALL_ACCESS);
343 } else {
344 return NT_STATUS_INVALID_HANDLE;
346 NT_STATUS_NOT_OK_RETURN(status);
348 (*r->out.sdbuf) = talloc(mem_ctx, struct sec_desc_buf);
349 NT_STATUS_HAVE_NO_MEMORY(*r->out.sdbuf);
351 (*r->out.sdbuf)->sd = sd;
353 return NT_STATUS_OK;
358 lsa_SetSecObj
360 static NTSTATUS dcesrv_lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
361 struct lsa_SetSecObj *r)
363 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
368 lsa_ChangePassword
370 static NTSTATUS dcesrv_lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
371 struct lsa_ChangePassword *r)
373 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
377 dssetup_DsRoleGetPrimaryDomainInformation
379 This is not an LSA call, but is the only call left on the DSSETUP
380 pipe (after the pipe was truncated), and needs lsa_get_policy_state
382 static WERROR dcesrv_dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state *dce_call,
383 TALLOC_CTX *mem_ctx,
384 struct dssetup_DsRoleGetPrimaryDomainInformation *r)
386 union dssetup_DsRoleInfo *info;
388 info = talloc(mem_ctx, union dssetup_DsRoleInfo);
389 W_ERROR_HAVE_NO_MEMORY(info);
391 switch (r->in.level) {
392 case DS_ROLE_BASIC_INFORMATION:
394 enum dssetup_DsRole role = DS_ROLE_STANDALONE_SERVER;
395 uint32_t flags = 0;
396 const char *domain = NULL;
397 const char *dns_domain = NULL;
398 const char *forest = NULL;
399 struct GUID domain_guid;
400 struct lsa_policy_state *state;
402 NTSTATUS status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
403 if (!NT_STATUS_IS_OK(status)) {
404 return ntstatus_to_werror(status);
407 ZERO_STRUCT(domain_guid);
409 switch (lp_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
410 case ROLE_STANDALONE:
411 role = DS_ROLE_STANDALONE_SERVER;
412 break;
413 case ROLE_DOMAIN_MEMBER:
414 role = DS_ROLE_MEMBER_SERVER;
415 break;
416 case ROLE_DOMAIN_CONTROLLER:
417 if (samdb_is_pdc(state->sam_ldb)) {
418 role = DS_ROLE_PRIMARY_DC;
419 } else {
420 role = DS_ROLE_BACKUP_DC;
422 break;
425 switch (lp_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
426 case ROLE_STANDALONE:
427 domain = talloc_strdup(mem_ctx, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx));
428 W_ERROR_HAVE_NO_MEMORY(domain);
429 break;
430 case ROLE_DOMAIN_MEMBER:
431 domain = talloc_strdup(mem_ctx, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx));
432 W_ERROR_HAVE_NO_MEMORY(domain);
433 /* TODO: what is with dns_domain and forest and guid? */
434 break;
435 case ROLE_DOMAIN_CONTROLLER:
436 flags = DS_ROLE_PRIMARY_DS_RUNNING;
438 if (state->mixed_domain == 1) {
439 flags |= DS_ROLE_PRIMARY_DS_MIXED_MODE;
442 domain = state->domain_name;
443 dns_domain = state->domain_dns;
444 forest = state->forest_dns;
446 domain_guid = state->domain_guid;
447 flags |= DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT;
448 break;
451 info->basic.role = role;
452 info->basic.flags = flags;
453 info->basic.domain = domain;
454 info->basic.dns_domain = dns_domain;
455 info->basic.forest = forest;
456 info->basic.domain_guid = domain_guid;
458 r->out.info = info;
459 return WERR_OK;
461 case DS_ROLE_UPGRADE_STATUS:
463 info->upgrade.upgrading = DS_ROLE_NOT_UPGRADING;
464 info->upgrade.previous_role = DS_ROLE_PREVIOUS_UNKNOWN;
466 r->out.info = info;
467 return WERR_OK;
469 case DS_ROLE_OP_STATUS:
471 info->opstatus.status = DS_ROLE_OP_IDLE;
473 r->out.info = info;
474 return WERR_OK;
476 default:
477 return WERR_INVALID_PARAM;
480 return WERR_INVALID_PARAM;
484 fill in the AccountDomain info
486 static NTSTATUS dcesrv_lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
487 struct lsa_DomainInfo *info)
489 info->name.string = state->domain_name;
490 info->sid = state->domain_sid;
492 return NT_STATUS_OK;
496 fill in the DNS domain info
498 static NTSTATUS dcesrv_lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
499 struct lsa_DnsDomainInfo *info)
501 info->name.string = state->domain_name;
502 info->sid = state->domain_sid;
503 info->dns_domain.string = state->domain_dns;
504 info->dns_forest.string = state->forest_dns;
505 info->domain_guid = state->domain_guid;
507 return NT_STATUS_OK;
511 lsa_QueryInfoPolicy2
513 static NTSTATUS dcesrv_lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
514 struct lsa_QueryInfoPolicy2 *r)
516 struct lsa_policy_state *state;
517 struct dcesrv_handle *h;
518 union lsa_PolicyInformation *info;
520 *r->out.info = NULL;
522 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
524 state = h->data;
526 info = talloc_zero(mem_ctx, union lsa_PolicyInformation);
527 if (!info) {
528 return NT_STATUS_NO_MEMORY;
530 *r->out.info = info;
532 switch (r->in.level) {
533 case LSA_POLICY_INFO_AUDIT_LOG:
534 /* we don't need to fill in any of this */
535 ZERO_STRUCT(info->audit_log);
536 return NT_STATUS_OK;
537 case LSA_POLICY_INFO_AUDIT_EVENTS:
538 /* we don't need to fill in any of this */
539 ZERO_STRUCT(info->audit_events);
540 return NT_STATUS_OK;
541 case LSA_POLICY_INFO_PD:
542 /* we don't need to fill in any of this */
543 ZERO_STRUCT(info->pd);
544 return NT_STATUS_OK;
546 case LSA_POLICY_INFO_DOMAIN:
547 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->domain);
548 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
549 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->account_domain);
550 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
551 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, i;
686 struct ldb_message **res;
687 const char * const attrs[] = { "objectSid", NULL};
688 uint32_t count;
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_NO_SUCH_USER;
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;
763 DCESRV_PULL_HANDLE(policy_handle, r->in.policy_handle, LSA_HANDLE_POLICY);
764 ZERO_STRUCTP(r->out.trustdom_handle);
766 policy_state = policy_handle->data;
768 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
769 if (!NT_STATUS_IS_OK(nt_status)) {
770 return nt_status;
773 netbios_name = r->in.info->netbios_name.string;
774 if (!netbios_name) {
775 return NT_STATUS_INVALID_PARAMETER;
778 dns_name = r->in.info->domain_name.string;
780 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
781 if (!trusted_domain_state) {
782 return NT_STATUS_NO_MEMORY;
784 trusted_domain_state->policy = policy_state;
786 if (strcasecmp(netbios_name, "BUILTIN") == 0
787 || (dns_name && strcasecmp(dns_name, "BUILTIN") == 0)
788 || (dom_sid_in_domain(policy_state->builtin_sid, r->in.info->sid))) {
789 return NT_STATUS_INVALID_PARAMETER;;
792 if (strcasecmp(netbios_name, policy_state->domain_name) == 0
793 || strcasecmp(netbios_name, policy_state->domain_dns) == 0
794 || (dns_name && strcasecmp(dns_name, policy_state->domain_dns) == 0)
795 || (dns_name && strcasecmp(dns_name, policy_state->domain_name) == 0)
796 || (dom_sid_equal(policy_state->domain_sid, r->in.info->sid))) {
797 return NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED;
800 /* While this is a REF pointer, some of the functions that wrap this don't provide this */
801 if (op == NDR_LSA_CREATETRUSTEDDOMAIN) {
802 /* No secrets are created at this time, for this function */
803 auth_struct.outgoing.count = 0;
804 auth_struct.incoming.count = 0;
805 } else {
806 auth_blob = data_blob_const(r->in.auth_info->auth_blob.data, r->in.auth_info->auth_blob.size);
807 arcfour_crypt_blob(auth_blob.data, auth_blob.length, &session_key);
808 ndr_err = ndr_pull_struct_blob(&auth_blob, mem_ctx,
809 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
810 &auth_struct,
811 (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
812 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
813 return NT_STATUS_INVALID_PARAMETER;
816 if (op == NDR_LSA_CREATETRUSTEDDOMAINEX) {
817 if (auth_struct.incoming.count > 1) {
818 return NT_STATUS_INVALID_PARAMETER;
823 if (auth_struct.incoming.count) {
824 int i;
825 struct trustAuthInOutBlob incoming;
827 incoming.count = auth_struct.incoming.count;
828 incoming.current = talloc(mem_ctx, struct AuthenticationInformationArray);
829 if (!incoming.current) {
830 return NT_STATUS_NO_MEMORY;
833 incoming.current->array = *auth_struct.incoming.current;
834 if (!incoming.current->array) {
835 return NT_STATUS_NO_MEMORY;
838 incoming.previous = talloc(mem_ctx, struct AuthenticationInformationArray);
839 if (!incoming.previous) {
840 return NT_STATUS_NO_MEMORY;
842 incoming.previous->array = talloc_array(mem_ctx, struct AuthenticationInformation, incoming.count);
843 if (!incoming.previous->array) {
844 return NT_STATUS_NO_MEMORY;
847 for (i = 0; i < incoming.count; i++) {
848 incoming.previous->array[i].LastUpdateTime = 0;
849 incoming.previous->array[i].AuthType = 0;
851 ndr_err = ndr_push_struct_blob(&trustAuthIncoming, mem_ctx,
852 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
853 &incoming,
854 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
855 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
856 return NT_STATUS_INVALID_PARAMETER;
858 } else {
859 trustAuthIncoming = data_blob(NULL, 0);
862 if (auth_struct.outgoing.count) {
863 int i;
864 struct trustAuthInOutBlob outgoing;
866 outgoing.count = auth_struct.outgoing.count;
867 outgoing.current = talloc(mem_ctx, struct AuthenticationInformationArray);
868 if (!outgoing.current) {
869 return NT_STATUS_NO_MEMORY;
872 outgoing.current->array = *auth_struct.outgoing.current;
873 if (!outgoing.current->array) {
874 return NT_STATUS_NO_MEMORY;
877 outgoing.previous = talloc(mem_ctx, struct AuthenticationInformationArray);
878 if (!outgoing.previous) {
879 return NT_STATUS_NO_MEMORY;
881 outgoing.previous->array = talloc_array(mem_ctx, struct AuthenticationInformation, outgoing.count);
882 if (!outgoing.previous->array) {
883 return NT_STATUS_NO_MEMORY;
886 for (i = 0; i < outgoing.count; i++) {
887 outgoing.previous->array[i].LastUpdateTime = 0;
888 outgoing.previous->array[i].AuthType = 0;
890 ndr_err = ndr_push_struct_blob(&trustAuthOutgoing, mem_ctx,
891 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
892 &outgoing,
893 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
894 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
895 return NT_STATUS_INVALID_PARAMETER;
897 } else {
898 trustAuthOutgoing = data_blob(NULL, 0);
901 ret = ldb_transaction_start(policy_state->sam_ldb);
902 if (ret != LDB_SUCCESS) {
903 return NT_STATUS_INTERNAL_DB_CORRUPTION;
906 if (dns_name) {
907 char *dns_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
908 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
909 /* search for the trusted_domain record */
910 ret = gendb_search(policy_state->sam_ldb,
911 mem_ctx, policy_state->system_dn, &msgs, attrs,
912 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s)(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))",
913 dns_encoded, dns_encoded, dns_encoded, netbios_encoded, netbios_encoded, netbios_encoded);
914 if (ret > 0) {
915 ldb_transaction_cancel(policy_state->sam_ldb);
916 return NT_STATUS_OBJECT_NAME_COLLISION;
918 } else {
919 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
920 /* search for the trusted_domain record */
921 ret = gendb_search(policy_state->sam_ldb,
922 mem_ctx, policy_state->system_dn, &msgs, attrs,
923 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))",
924 netbios_encoded, netbios_encoded, netbios_encoded);
925 if (ret > 0) {
926 ldb_transaction_cancel(policy_state->sam_ldb);
927 return NT_STATUS_OBJECT_NAME_COLLISION;
931 if (ret < 0 ) {
932 ldb_transaction_cancel(policy_state->sam_ldb);
933 return NT_STATUS_INTERNAL_DB_CORRUPTION;
936 name = dns_name ? dns_name : netbios_name;
938 msg = ldb_msg_new(mem_ctx);
939 if (msg == NULL) {
940 return NT_STATUS_NO_MEMORY;
943 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
944 if ( ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name)) {
945 ldb_transaction_cancel(policy_state->sam_ldb);
946 return NT_STATUS_NO_MEMORY;
949 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "flatname", netbios_name);
951 if (r->in.info->sid) {
952 const char *sid_string = dom_sid_string(mem_ctx, r->in.info->sid);
953 if (!sid_string) {
954 ldb_transaction_cancel(policy_state->sam_ldb);
955 return NT_STATUS_NO_MEMORY;
958 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "securityIdentifier", sid_string);
961 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "objectClass", "trustedDomain");
963 samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustType", r->in.info->trust_type);
965 samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustAttributes", r->in.info->trust_attributes);
967 samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustDirection", r->in.info->trust_direction);
969 if (dns_name) {
970 samdb_msg_add_string(trusted_domain_state->policy->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(policy_state->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(policy_state->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(trusted_domain_state->policy->sam_ldb, msg);
992 switch (ret) {
993 case LDB_SUCCESS:
994 break;
995 case LDB_ERR_ENTRY_ALREADY_EXISTS:
996 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
997 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
998 ldb_dn_get_linearized(msg->dn),
999 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
1000 return NT_STATUS_DOMAIN_EXISTS;
1001 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1002 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
1003 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
1004 ldb_dn_get_linearized(msg->dn),
1005 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
1006 return NT_STATUS_ACCESS_DENIED;
1007 default:
1008 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
1009 DEBUG(0,("Failed to create user record %s: %s\n",
1010 ldb_dn_get_linearized(msg->dn),
1011 ldb_errstring(trusted_domain_state->policy->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(trusted_domain_state->policy->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(policy_state->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(policy_state->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(trusted_domain_state->policy->sam_ldb, mem_ctx, msg_user,
1042 "userAccountControl",
1043 UF_INTERDOMAIN_TRUST_ACCOUNT) != 0) {
1044 ldb_transaction_cancel(policy_state->sam_ldb);
1045 return NT_STATUS_NO_MEMORY;
1048 if (auth_struct.incoming.count) {
1049 int 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(trusted_domain_state->policy->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(policy_state->sam_ldb);
1061 return NT_STATUS_NO_MEMORY;
1067 /* create the cn=users trusted_domain account */
1068 ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg_user);
1069 switch (ret) {
1070 case LDB_SUCCESS:
1071 break;
1072 case LDB_ERR_ENTRY_ALREADY_EXISTS:
1073 ldb_transaction_cancel(trusted_domain_state->policy->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(trusted_domain_state->policy->sam_ldb)));
1077 return NT_STATUS_DOMAIN_EXISTS;
1078 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1079 ldb_transaction_cancel(trusted_domain_state->policy->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(trusted_domain_state->policy->sam_ldb)));
1083 return NT_STATUS_ACCESS_DENIED;
1084 default:
1085 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
1086 DEBUG(0,("Failed to create user record %s: %s\n",
1087 ldb_dn_get_linearized(msg_user->dn),
1088 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
1089 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1093 ret = ldb_transaction_commit(policy_state->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
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 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1283 mem_ctx, policy_state->system_dn, &msgs, attrs,
1284 "(&(flatname=%s)(objectclass=trustedDomain))",
1285 ldb_binary_encode_string(mem_ctx, r->in.name.string));
1286 if (ret == 0) {
1287 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1290 if (ret != 1) {
1291 DEBUG(0,("Found %d records matching DN %s\n", ret,
1292 ldb_dn_get_linearized(policy_state->system_dn)));
1293 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1296 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
1298 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1299 if (!handle) {
1300 return NT_STATUS_NO_MEMORY;
1303 handle->data = talloc_steal(handle, trusted_domain_state);
1305 trusted_domain_state->access_mask = r->in.access_mask;
1306 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1308 *r->out.trustdom_handle = handle->wire_handle;
1310 return NT_STATUS_OK;
1316 lsa_SetTrustedDomainInfo
1318 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1319 struct lsa_SetTrustedDomainInfo *r)
1321 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1327 lsa_SetInfomrationTrustedDomain
1329 static NTSTATUS dcesrv_lsa_SetInformationTrustedDomain(struct dcesrv_call_state *dce_call,
1330 TALLOC_CTX *mem_ctx,
1331 struct lsa_SetInformationTrustedDomain *r)
1333 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1338 lsa_DeleteTrustedDomain
1340 static NTSTATUS dcesrv_lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1341 struct lsa_DeleteTrustedDomain *r)
1343 NTSTATUS status;
1344 struct lsa_OpenTrustedDomain opn;
1345 struct lsa_DeleteObject del;
1346 struct dcesrv_handle *h;
1348 opn.in.handle = r->in.handle;
1349 opn.in.sid = r->in.dom_sid;
1350 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1351 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1352 if (!opn.out.trustdom_handle) {
1353 return NT_STATUS_NO_MEMORY;
1355 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
1356 if (!NT_STATUS_IS_OK(status)) {
1357 return status;
1360 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
1361 talloc_steal(mem_ctx, h);
1363 del.in.handle = opn.out.trustdom_handle;
1364 del.out.handle = opn.out.trustdom_handle;
1365 status = dcesrv_lsa_DeleteObject(dce_call, mem_ctx, &del);
1366 if (!NT_STATUS_IS_OK(status)) {
1367 return status;
1369 return NT_STATUS_OK;
1372 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx,
1373 struct ldb_message *msg,
1374 struct lsa_TrustDomainInfoInfoEx *info_ex)
1376 info_ex->domain_name.string
1377 = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
1378 info_ex->netbios_name.string
1379 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1380 info_ex->sid
1381 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1382 info_ex->trust_direction
1383 = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
1384 info_ex->trust_type
1385 = ldb_msg_find_attr_as_int(msg, "trustType", 0);
1386 info_ex->trust_attributes
1387 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);
1388 return NT_STATUS_OK;
1392 lsa_QueryTrustedDomainInfo
1394 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1395 struct lsa_QueryTrustedDomainInfo *r)
1397 union lsa_TrustedDomainInfo *info = NULL;
1398 struct dcesrv_handle *h;
1399 struct lsa_trusted_domain_state *trusted_domain_state;
1400 struct ldb_message *msg;
1401 int ret;
1402 struct ldb_message **res;
1403 const char *attrs[] = {
1404 "flatname",
1405 "trustPartner",
1406 "securityIdentifier",
1407 "trustDirection",
1408 "trustType",
1409 "trustAttributes",
1410 "msDs-supportedEncryptionTypes",
1411 NULL
1414 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
1416 trusted_domain_state = talloc_get_type(h->data, struct lsa_trusted_domain_state);
1418 /* pull all the user attributes */
1419 ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
1420 trusted_domain_state->trusted_domain_dn, &res, attrs);
1421 if (ret != 1) {
1422 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1424 msg = res[0];
1426 info = talloc_zero(mem_ctx, union lsa_TrustedDomainInfo);
1427 if (!info) {
1428 return NT_STATUS_NO_MEMORY;
1430 *r->out.info = info;
1432 switch (r->in.level) {
1433 case LSA_TRUSTED_DOMAIN_INFO_NAME:
1434 info->name.netbios_name.string
1435 = samdb_result_string(msg, "flatname", NULL);
1436 break;
1437 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1438 info->posix_offset.posix_offset
1439 = samdb_result_uint(msg, "posixOffset", 0);
1440 break;
1441 #if 0 /* Win2k3 doesn't implement this */
1442 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
1443 r->out.info->info_basic.netbios_name.string
1444 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1445 r->out.info->info_basic.sid
1446 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1447 break;
1448 #endif
1449 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1450 return fill_trust_domain_ex(mem_ctx, msg, &info->info_ex);
1452 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1453 ZERO_STRUCT(info->full_info);
1454 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info.info_ex);
1456 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
1457 ZERO_STRUCT(info->full_info2_internal);
1458 info->full_info2_internal.posix_offset.posix_offset
1459 = samdb_result_uint(msg, "posixOffset", 0);
1460 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info2_internal.info.info_ex);
1462 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
1463 info->enc_types.enc_types
1464 = samdb_result_uint(msg, "msDs-supportedEncryptionTypes", KERB_ENCTYPE_RC4_HMAC_MD5);
1465 break;
1467 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
1468 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
1469 /* oops, we don't want to return the info after all */
1470 talloc_free(info);
1471 *r->out.info = NULL;
1472 return NT_STATUS_INVALID_PARAMETER;
1473 default:
1474 /* oops, we don't want to return the info after all */
1475 talloc_free(info);
1476 *r->out.info = NULL;
1477 return NT_STATUS_INVALID_INFO_CLASS;
1480 return NT_STATUS_OK;
1485 lsa_QueryTrustedDomainInfoBySid
1487 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1488 struct lsa_QueryTrustedDomainInfoBySid *r)
1490 NTSTATUS status;
1491 struct lsa_OpenTrustedDomain opn;
1492 struct lsa_QueryTrustedDomainInfo query;
1493 struct dcesrv_handle *h;
1495 opn.in.handle = r->in.handle;
1496 opn.in.sid = r->in.dom_sid;
1497 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1498 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1499 if (!opn.out.trustdom_handle) {
1500 return NT_STATUS_NO_MEMORY;
1502 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
1503 if (!NT_STATUS_IS_OK(status)) {
1504 return status;
1507 /* Ensure this handle goes away at the end of this call */
1508 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
1509 talloc_steal(mem_ctx, h);
1511 query.in.trustdom_handle = opn.out.trustdom_handle;
1512 query.in.level = r->in.level;
1513 query.out.info = r->out.info;
1514 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1515 if (!NT_STATUS_IS_OK(status)) {
1516 return status;
1519 return NT_STATUS_OK;
1523 lsa_SetTrustedDomainInfoByName
1525 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1526 TALLOC_CTX *mem_ctx,
1527 struct lsa_SetTrustedDomainInfoByName *r)
1529 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1533 lsa_QueryTrustedDomainInfoByName
1535 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1536 TALLOC_CTX *mem_ctx,
1537 struct lsa_QueryTrustedDomainInfoByName *r)
1539 NTSTATUS status;
1540 struct lsa_OpenTrustedDomainByName opn;
1541 struct lsa_QueryTrustedDomainInfo query;
1542 struct dcesrv_handle *h;
1544 opn.in.handle = r->in.handle;
1545 opn.in.name = *r->in.trusted_domain;
1546 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1547 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1548 if (!opn.out.trustdom_handle) {
1549 return NT_STATUS_NO_MEMORY;
1551 status = dcesrv_lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &opn);
1552 if (!NT_STATUS_IS_OK(status)) {
1553 return status;
1556 /* Ensure this handle goes away at the end of this call */
1557 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
1558 talloc_steal(mem_ctx, h);
1560 query.in.trustdom_handle = opn.out.trustdom_handle;
1561 query.in.level = r->in.level;
1562 query.out.info = r->out.info;
1563 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1564 if (!NT_STATUS_IS_OK(status)) {
1565 return status;
1568 return NT_STATUS_OK;
1572 lsa_CloseTrustedDomainEx
1574 static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
1575 TALLOC_CTX *mem_ctx,
1576 struct lsa_CloseTrustedDomainEx *r)
1578 /* The result of a bad hair day from an IDL programmer? Not
1579 * implmented in Win2k3. You should always just lsa_Close
1580 * anyway. */
1581 return NT_STATUS_NOT_IMPLEMENTED;
1586 comparison function for sorting lsa_DomainInformation array
1588 static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
1590 return strcasecmp_m(e1->name.string, e2->name.string);
1594 lsa_EnumTrustDom
1596 static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1597 struct lsa_EnumTrustDom *r)
1599 struct dcesrv_handle *policy_handle;
1600 struct lsa_DomainInfo *entries;
1601 struct lsa_policy_state *policy_state;
1602 struct ldb_message **domains;
1603 const char *attrs[] = {
1604 "flatname",
1605 "securityIdentifier",
1606 NULL
1610 int count, i;
1612 *r->out.resume_handle = 0;
1614 r->out.domains->domains = NULL;
1615 r->out.domains->count = 0;
1617 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1619 policy_state = policy_handle->data;
1621 /* search for all users in this domain. This could possibly be cached and
1622 resumed based on resume_key */
1623 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1624 "objectclass=trustedDomain");
1625 if (count == -1) {
1626 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1629 /* convert to lsa_TrustInformation format */
1630 entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
1631 if (!entries) {
1632 return NT_STATUS_NO_MEMORY;
1634 for (i=0;i<count;i++) {
1635 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
1636 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
1639 /* sort the results by name */
1640 qsort(entries, count, sizeof(*entries),
1641 (comparison_fn_t)compare_DomainInfo);
1643 if (*r->in.resume_handle >= count) {
1644 *r->out.resume_handle = -1;
1646 return NT_STATUS_NO_MORE_ENTRIES;
1649 /* return the rest, limit by max_size. Note that we
1650 use the w2k3 element size value of 60 */
1651 r->out.domains->count = count - *r->in.resume_handle;
1652 r->out.domains->count = MIN(r->out.domains->count,
1653 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
1655 r->out.domains->domains = entries + *r->in.resume_handle;
1656 r->out.domains->count = r->out.domains->count;
1658 if (r->out.domains->count < count - *r->in.resume_handle) {
1659 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1660 return STATUS_MORE_ENTRIES;
1663 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
1664 * always be larger than the previous input resume handle, in
1665 * particular when hitting the last query it is vital to set the
1666 * resume handle correctly to avoid infinite client loops, as
1667 * seen e.g. with Windows XP SP3 when resume handle is 0 and
1668 * status is NT_STATUS_OK - gd */
1670 *r->out.resume_handle = (uint32_t)-1;
1672 return NT_STATUS_OK;
1676 comparison function for sorting lsa_DomainInformation array
1678 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
1680 return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
1684 lsa_EnumTrustedDomainsEx
1686 static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1687 struct lsa_EnumTrustedDomainsEx *r)
1689 struct dcesrv_handle *policy_handle;
1690 struct lsa_TrustDomainInfoInfoEx *entries;
1691 struct lsa_policy_state *policy_state;
1692 struct ldb_message **domains;
1693 const char *attrs[] = {
1694 "flatname",
1695 "trustPartner",
1696 "securityIdentifier",
1697 "trustDirection",
1698 "trustType",
1699 "trustAttributes",
1700 NULL
1702 NTSTATUS nt_status;
1704 int count, i;
1706 *r->out.resume_handle = 0;
1708 r->out.domains->domains = NULL;
1709 r->out.domains->count = 0;
1711 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1713 policy_state = policy_handle->data;
1715 /* search for all users in this domain. This could possibly be cached and
1716 resumed based on resume_key */
1717 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1718 "objectclass=trustedDomain");
1719 if (count == -1) {
1720 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1723 /* convert to lsa_DomainInformation format */
1724 entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
1725 if (!entries) {
1726 return NT_STATUS_NO_MEMORY;
1728 for (i=0;i<count;i++) {
1729 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
1730 if (!NT_STATUS_IS_OK(nt_status)) {
1731 return nt_status;
1735 /* sort the results by name */
1736 qsort(entries, count, sizeof(*entries),
1737 (comparison_fn_t)compare_TrustDomainInfoInfoEx);
1739 if (*r->in.resume_handle >= count) {
1740 *r->out.resume_handle = -1;
1742 return NT_STATUS_NO_MORE_ENTRIES;
1745 /* return the rest, limit by max_size. Note that we
1746 use the w2k3 element size value of 60 */
1747 r->out.domains->count = count - *r->in.resume_handle;
1748 r->out.domains->count = MIN(r->out.domains->count,
1749 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
1751 r->out.domains->domains = entries + *r->in.resume_handle;
1752 r->out.domains->count = r->out.domains->count;
1754 if (r->out.domains->count < count - *r->in.resume_handle) {
1755 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1756 return STATUS_MORE_ENTRIES;
1759 return NT_STATUS_OK;
1764 lsa_OpenAccount
1766 static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1767 struct lsa_OpenAccount *r)
1769 struct dcesrv_handle *h, *ah;
1770 struct lsa_policy_state *state;
1771 struct lsa_account_state *astate;
1773 ZERO_STRUCTP(r->out.acct_handle);
1775 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1777 state = h->data;
1779 astate = talloc(dce_call->conn, struct lsa_account_state);
1780 if (astate == NULL) {
1781 return NT_STATUS_NO_MEMORY;
1784 astate->account_sid = dom_sid_dup(astate, r->in.sid);
1785 if (astate->account_sid == NULL) {
1786 talloc_free(astate);
1787 return NT_STATUS_NO_MEMORY;
1790 astate->policy = talloc_reference(astate, state);
1791 astate->access_mask = r->in.access_mask;
1793 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
1794 if (!ah) {
1795 talloc_free(astate);
1796 return NT_STATUS_NO_MEMORY;
1799 ah->data = talloc_steal(ah, astate);
1801 *r->out.acct_handle = ah->wire_handle;
1803 return NT_STATUS_OK;
1808 lsa_EnumPrivsAccount
1810 static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
1811 TALLOC_CTX *mem_ctx,
1812 struct lsa_EnumPrivsAccount *r)
1814 struct dcesrv_handle *h;
1815 struct lsa_account_state *astate;
1816 int ret, i;
1817 struct ldb_message **res;
1818 const char * const attrs[] = { "privilege", NULL};
1819 struct ldb_message_element *el;
1820 const char *sidstr;
1821 struct lsa_PrivilegeSet *privs;
1823 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1825 astate = h->data;
1827 privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
1828 if (privs == NULL) {
1829 return NT_STATUS_NO_MEMORY;
1831 privs->count = 0;
1832 privs->unknown = 0;
1833 privs->set = NULL;
1835 *r->out.privs = privs;
1837 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
1838 if (sidstr == NULL) {
1839 return NT_STATUS_NO_MEMORY;
1842 ret = gendb_search(astate->policy->pdb, mem_ctx, NULL, &res, attrs,
1843 "objectSid=%s", sidstr);
1844 if (ret != 1) {
1845 return NT_STATUS_OK;
1848 el = ldb_msg_find_element(res[0], "privilege");
1849 if (el == NULL || el->num_values == 0) {
1850 return NT_STATUS_OK;
1853 privs->set = talloc_array(privs,
1854 struct lsa_LUIDAttribute, el->num_values);
1855 if (privs->set == NULL) {
1856 return NT_STATUS_NO_MEMORY;
1859 for (i=0;i<el->num_values;i++) {
1860 int id = sec_privilege_id((const char *)el->values[i].data);
1861 if (id == -1) {
1862 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1864 privs->set[i].attribute = 0;
1865 privs->set[i].luid.low = id;
1866 privs->set[i].luid.high = 0;
1869 privs->count = el->num_values;
1871 return NT_STATUS_OK;
1875 lsa_EnumAccountRights
1877 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
1878 TALLOC_CTX *mem_ctx,
1879 struct lsa_EnumAccountRights *r)
1881 struct dcesrv_handle *h;
1882 struct lsa_policy_state *state;
1883 int ret, i;
1884 struct ldb_message **res;
1885 const char * const attrs[] = { "privilege", NULL};
1886 const char *sidstr;
1887 struct ldb_message_element *el;
1889 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1891 state = h->data;
1893 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
1894 if (sidstr == NULL) {
1895 return NT_STATUS_NO_MEMORY;
1898 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
1899 "(&(objectSid=%s)(privilege=*))", sidstr);
1900 if (ret == 0) {
1901 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1903 if (ret > 1) {
1904 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1906 if (ret == -1) {
1907 DEBUG(3, ("searching for account rights for SID: %s failed: %s",
1908 dom_sid_string(mem_ctx, r->in.sid),
1909 ldb_errstring(state->pdb)));
1910 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1913 el = ldb_msg_find_element(res[0], "privilege");
1914 if (el == NULL || el->num_values == 0) {
1915 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1918 r->out.rights->count = el->num_values;
1919 r->out.rights->names = talloc_array(r->out.rights,
1920 struct lsa_StringLarge, r->out.rights->count);
1921 if (r->out.rights->names == NULL) {
1922 return NT_STATUS_NO_MEMORY;
1925 for (i=0;i<el->num_values;i++) {
1926 r->out.rights->names[i].string = (const char *)el->values[i].data;
1929 return NT_STATUS_OK;
1935 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
1937 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
1938 TALLOC_CTX *mem_ctx,
1939 struct lsa_policy_state *state,
1940 int ldb_flag,
1941 struct dom_sid *sid,
1942 const struct lsa_RightSet *rights)
1944 const char *sidstr, *sidndrstr;
1945 struct ldb_message *msg;
1946 struct ldb_message_element *el;
1947 int i, ret;
1948 struct lsa_EnumAccountRights r2;
1949 char *dnstr;
1951 if (security_session_user_level(dce_call->conn->auth_state.session_info) <
1952 SECURITY_ADMINISTRATOR) {
1953 DEBUG(0,("lsa_AddRemoveAccount refused for supplied security token\n"));
1954 return NT_STATUS_ACCESS_DENIED;
1957 msg = ldb_msg_new(mem_ctx);
1958 if (msg == NULL) {
1959 return NT_STATUS_NO_MEMORY;
1962 sidndrstr = ldap_encode_ndr_dom_sid(msg, sid);
1963 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidndrstr, msg);
1965 sidstr = dom_sid_string(msg, sid);
1966 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidstr, msg);
1968 dnstr = talloc_asprintf(msg, "sid=%s", sidstr);
1969 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(dnstr, msg);
1971 msg->dn = ldb_dn_new(msg, state->pdb, dnstr);
1972 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg->dn, msg);
1974 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1975 NTSTATUS status;
1977 r2.in.handle = &state->handle->wire_handle;
1978 r2.in.sid = sid;
1979 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
1981 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1982 if (!NT_STATUS_IS_OK(status)) {
1983 ZERO_STRUCTP(r2.out.rights);
1987 for (i=0;i<rights->count;i++) {
1988 if (sec_privilege_id(rights->names[i].string) == -1) {
1989 talloc_free(msg);
1990 return NT_STATUS_NO_SUCH_PRIVILEGE;
1993 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1994 int j;
1995 for (j=0;j<r2.out.rights->count;j++) {
1996 if (strcasecmp_m(r2.out.rights->names[j].string,
1997 rights->names[i].string) == 0) {
1998 break;
2001 if (j != r2.out.rights->count) continue;
2004 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
2005 if (ret != LDB_SUCCESS) {
2006 talloc_free(msg);
2007 return NT_STATUS_NO_MEMORY;
2011 el = ldb_msg_find_element(msg, "privilege");
2012 if (!el) {
2013 talloc_free(msg);
2014 return NT_STATUS_OK;
2017 el->flags = ldb_flag;
2019 ret = ldb_modify(state->pdb, msg);
2020 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
2021 if (samdb_msg_add_dom_sid(state->pdb, msg, msg, "objectSid", sid) != LDB_SUCCESS) {
2022 talloc_free(msg);
2023 return NT_STATUS_NO_MEMORY;
2025 samdb_msg_add_string(state->pdb, msg, msg, "comment", "added via LSA");
2026 ret = ldb_add(state->pdb, msg);
2028 if (ret != 0) {
2029 if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
2030 talloc_free(msg);
2031 return NT_STATUS_OK;
2033 DEBUG(3, ("Could not %s attributes from %s: %s",
2034 ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add",
2035 ldb_dn_get_linearized(msg->dn), ldb_errstring(state->pdb)));
2036 talloc_free(msg);
2037 return NT_STATUS_UNEXPECTED_IO_ERROR;
2040 talloc_free(msg);
2041 return NT_STATUS_OK;
2045 lsa_AddPrivilegesToAccount
2047 static NTSTATUS dcesrv_lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2048 struct lsa_AddPrivilegesToAccount *r)
2050 struct lsa_RightSet rights;
2051 struct dcesrv_handle *h;
2052 struct lsa_account_state *astate;
2053 int i;
2055 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2057 astate = h->data;
2059 rights.count = r->in.privs->count;
2060 rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
2061 if (rights.names == NULL) {
2062 return NT_STATUS_NO_MEMORY;
2064 for (i=0;i<rights.count;i++) {
2065 int id = r->in.privs->set[i].luid.low;
2066 if (r->in.privs->set[i].luid.high) {
2067 return NT_STATUS_NO_SUCH_PRIVILEGE;
2069 rights.names[i].string = sec_privilege_name(id);
2070 if (rights.names[i].string == NULL) {
2071 return NT_STATUS_NO_SUCH_PRIVILEGE;
2075 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2076 LDB_FLAG_MOD_ADD, astate->account_sid,
2077 &rights);
2082 lsa_RemovePrivilegesFromAccount
2084 static NTSTATUS dcesrv_lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2085 struct lsa_RemovePrivilegesFromAccount *r)
2087 struct lsa_RightSet *rights;
2088 struct dcesrv_handle *h;
2089 struct lsa_account_state *astate;
2090 int i;
2092 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2094 astate = h->data;
2096 rights = talloc(mem_ctx, struct lsa_RightSet);
2098 if (r->in.remove_all == 1 &&
2099 r->in.privs == NULL) {
2100 struct lsa_EnumAccountRights r2;
2101 NTSTATUS status;
2103 r2.in.handle = &astate->policy->handle->wire_handle;
2104 r2.in.sid = astate->account_sid;
2105 r2.out.rights = rights;
2107 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
2108 if (!NT_STATUS_IS_OK(status)) {
2109 return status;
2112 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2113 LDB_FLAG_MOD_DELETE, astate->account_sid,
2114 r2.out.rights);
2117 if (r->in.remove_all != 0) {
2118 return NT_STATUS_INVALID_PARAMETER;
2121 rights->count = r->in.privs->count;
2122 rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
2123 if (rights->names == NULL) {
2124 return NT_STATUS_NO_MEMORY;
2126 for (i=0;i<rights->count;i++) {
2127 int id = r->in.privs->set[i].luid.low;
2128 if (r->in.privs->set[i].luid.high) {
2129 return NT_STATUS_NO_SUCH_PRIVILEGE;
2131 rights->names[i].string = sec_privilege_name(id);
2132 if (rights->names[i].string == NULL) {
2133 return NT_STATUS_NO_SUCH_PRIVILEGE;
2137 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2138 LDB_FLAG_MOD_DELETE, astate->account_sid,
2139 rights);
2144 lsa_GetQuotasForAccount
2146 static NTSTATUS dcesrv_lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2147 struct lsa_GetQuotasForAccount *r)
2149 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2154 lsa_SetQuotasForAccount
2156 static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2157 struct lsa_SetQuotasForAccount *r)
2159 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2164 lsa_GetSystemAccessAccount
2166 static NTSTATUS dcesrv_lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2167 struct lsa_GetSystemAccessAccount *r)
2169 int i;
2170 NTSTATUS status;
2171 struct lsa_EnumPrivsAccount enumPrivs;
2172 struct lsa_PrivilegeSet *privs;
2174 privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
2175 if (!privs) {
2176 return NT_STATUS_NO_MEMORY;
2178 privs->count = 0;
2179 privs->unknown = 0;
2180 privs->set = NULL;
2182 enumPrivs.in.handle = r->in.handle;
2183 enumPrivs.out.privs = &privs;
2185 status = dcesrv_lsa_EnumPrivsAccount(dce_call, mem_ctx, &enumPrivs);
2186 if (!NT_STATUS_IS_OK(status)) {
2187 return status;
2190 *(r->out.access_mask) = 0x00000000;
2192 for (i = 0; i < privs->count; i++) {
2193 int priv = privs->set[i].luid.low;
2195 switch (priv) {
2196 case SEC_PRIV_INTERACTIVE_LOGON:
2197 *(r->out.access_mask) |= LSA_POLICY_MODE_INTERACTIVE;
2198 break;
2199 case SEC_PRIV_NETWORK_LOGON:
2200 *(r->out.access_mask) |= LSA_POLICY_MODE_NETWORK;
2201 break;
2202 case SEC_PRIV_REMOTE_INTERACTIVE_LOGON:
2203 *(r->out.access_mask) |= LSA_POLICY_MODE_REMOTE_INTERACTIVE;
2204 break;
2208 return NT_STATUS_OK;
2213 lsa_SetSystemAccessAccount
2215 static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2216 struct lsa_SetSystemAccessAccount *r)
2218 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2223 lsa_CreateSecret
2225 static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2226 struct lsa_CreateSecret *r)
2228 struct dcesrv_handle *policy_handle;
2229 struct lsa_policy_state *policy_state;
2230 struct lsa_secret_state *secret_state;
2231 struct dcesrv_handle *handle;
2232 struct ldb_message **msgs, *msg;
2233 const char *attrs[] = {
2234 NULL
2237 const char *name;
2239 int ret;
2241 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2242 ZERO_STRUCTP(r->out.sec_handle);
2244 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2246 case SECURITY_SYSTEM:
2247 case SECURITY_ADMINISTRATOR:
2248 break;
2249 default:
2250 /* Users and annonymous are not allowed create secrets */
2251 return NT_STATUS_ACCESS_DENIED;
2254 policy_state = policy_handle->data;
2256 if (!r->in.name.string) {
2257 return NT_STATUS_INVALID_PARAMETER;
2260 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2261 if (!secret_state) {
2262 return NT_STATUS_NO_MEMORY;
2264 secret_state->policy = policy_state;
2266 msg = ldb_msg_new(mem_ctx);
2267 if (msg == NULL) {
2268 return NT_STATUS_NO_MEMORY;
2271 if (strncmp("G$", r->in.name.string, 2) == 0) {
2272 const char *name2;
2273 name = &r->in.name.string[2];
2274 /* 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) */
2275 secret_state->sam_ldb = talloc_reference(secret_state,
2276 samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(dce_call->conn->dce_ctx->lp_ctx)));
2277 secret_state->global = true;
2279 if (strlen(name) < 1) {
2280 return NT_STATUS_INVALID_PARAMETER;
2283 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
2284 /* search for the secret record */
2285 ret = gendb_search(secret_state->sam_ldb,
2286 mem_ctx, policy_state->system_dn, &msgs, attrs,
2287 "(&(cn=%s)(objectclass=secret))",
2288 name2);
2289 if (ret > 0) {
2290 return NT_STATUS_OBJECT_NAME_COLLISION;
2293 if (ret == -1) {
2294 DEBUG(0,("Failure searching for CN=%s: %s\n",
2295 name2, ldb_errstring(secret_state->sam_ldb)));
2296 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2299 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
2300 if (!name2 || ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
2301 return NT_STATUS_NO_MEMORY;
2304 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
2306 } else {
2307 secret_state->global = false;
2309 name = r->in.name.string;
2310 if (strlen(name) < 1) {
2311 return NT_STATUS_INVALID_PARAMETER;
2314 secret_state->sam_ldb = talloc_reference(secret_state,
2315 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
2316 /* search for the secret record */
2317 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2318 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2319 &msgs, attrs,
2320 "(&(cn=%s)(objectclass=secret))",
2321 ldb_binary_encode_string(mem_ctx, name));
2322 if (ret > 0) {
2323 return NT_STATUS_OBJECT_NAME_COLLISION;
2326 if (ret == -1) {
2327 DEBUG(0,("Failure searching for CN=%s: %s\n",
2328 name, ldb_errstring(secret_state->sam_ldb)));
2329 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2332 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name);
2333 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
2336 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
2338 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
2340 /* create the secret */
2341 ret = ldb_add(secret_state->sam_ldb, msg);
2342 if (ret != 0) {
2343 DEBUG(0,("Failed to create secret record %s: %s\n",
2344 ldb_dn_get_linearized(msg->dn),
2345 ldb_errstring(secret_state->sam_ldb)));
2346 return NT_STATUS_ACCESS_DENIED;
2349 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2350 if (!handle) {
2351 return NT_STATUS_NO_MEMORY;
2354 handle->data = talloc_steal(handle, secret_state);
2356 secret_state->access_mask = r->in.access_mask;
2357 secret_state->policy = talloc_reference(secret_state, policy_state);
2359 *r->out.sec_handle = handle->wire_handle;
2361 return NT_STATUS_OK;
2366 lsa_OpenSecret
2368 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2369 struct lsa_OpenSecret *r)
2371 struct dcesrv_handle *policy_handle;
2373 struct lsa_policy_state *policy_state;
2374 struct lsa_secret_state *secret_state;
2375 struct dcesrv_handle *handle;
2376 struct ldb_message **msgs;
2377 const char *attrs[] = {
2378 NULL
2381 const char *name;
2383 int ret;
2385 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2386 ZERO_STRUCTP(r->out.sec_handle);
2387 policy_state = policy_handle->data;
2389 if (!r->in.name.string) {
2390 return NT_STATUS_INVALID_PARAMETER;
2393 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2395 case SECURITY_SYSTEM:
2396 case SECURITY_ADMINISTRATOR:
2397 break;
2398 default:
2399 /* Users and annonymous are not allowed to access secrets */
2400 return NT_STATUS_ACCESS_DENIED;
2403 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2404 if (!secret_state) {
2405 return NT_STATUS_NO_MEMORY;
2407 secret_state->policy = policy_state;
2409 if (strncmp("G$", r->in.name.string, 2) == 0) {
2410 name = &r->in.name.string[2];
2411 /* 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) */
2412 secret_state->sam_ldb = talloc_reference(secret_state,
2413 samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(dce_call->conn->dce_ctx->lp_ctx)));
2414 secret_state->global = true;
2416 if (strlen(name) < 1) {
2417 return NT_STATUS_INVALID_PARAMETER;
2420 /* search for the secret record */
2421 ret = gendb_search(secret_state->sam_ldb,
2422 mem_ctx, policy_state->system_dn, &msgs, attrs,
2423 "(&(cn=%s Secret)(objectclass=secret))",
2424 ldb_binary_encode_string(mem_ctx, name));
2425 if (ret == 0) {
2426 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2429 if (ret != 1) {
2430 DEBUG(0,("Found %d records matching DN %s\n", ret,
2431 ldb_dn_get_linearized(policy_state->system_dn)));
2432 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2435 } else {
2436 secret_state->global = false;
2437 secret_state->sam_ldb = talloc_reference(secret_state,
2438 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
2440 name = r->in.name.string;
2441 if (strlen(name) < 1) {
2442 return NT_STATUS_INVALID_PARAMETER;
2445 /* search for the secret record */
2446 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2447 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2448 &msgs, attrs,
2449 "(&(cn=%s)(objectclass=secret))",
2450 ldb_binary_encode_string(mem_ctx, name));
2451 if (ret == 0) {
2452 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2455 if (ret != 1) {
2456 DEBUG(0,("Found %d records matching CN=%s\n",
2457 ret, ldb_binary_encode_string(mem_ctx, name)));
2458 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2462 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
2464 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2465 if (!handle) {
2466 return NT_STATUS_NO_MEMORY;
2469 handle->data = talloc_steal(handle, secret_state);
2471 secret_state->access_mask = r->in.access_mask;
2472 secret_state->policy = talloc_reference(secret_state, policy_state);
2474 *r->out.sec_handle = handle->wire_handle;
2476 return NT_STATUS_OK;
2481 lsa_SetSecret
2483 static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2484 struct lsa_SetSecret *r)
2487 struct dcesrv_handle *h;
2488 struct lsa_secret_state *secret_state;
2489 struct ldb_message *msg;
2490 DATA_BLOB session_key;
2491 DATA_BLOB crypt_secret, secret;
2492 struct ldb_val val;
2493 int ret;
2494 NTSTATUS status = NT_STATUS_OK;
2496 struct timeval now = timeval_current();
2497 NTTIME nt_now = timeval_to_nttime(&now);
2499 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2501 secret_state = h->data;
2503 msg = ldb_msg_new(mem_ctx);
2504 if (msg == NULL) {
2505 return NT_STATUS_NO_MEMORY;
2508 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
2509 if (!msg->dn) {
2510 return NT_STATUS_NO_MEMORY;
2512 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2513 if (!NT_STATUS_IS_OK(status)) {
2514 return status;
2517 if (r->in.old_val) {
2518 /* Decrypt */
2519 crypt_secret.data = r->in.old_val->data;
2520 crypt_secret.length = r->in.old_val->size;
2522 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2523 if (!NT_STATUS_IS_OK(status)) {
2524 return status;
2527 val.data = secret.data;
2528 val.length = secret.length;
2530 /* set value */
2531 if (samdb_msg_add_value(secret_state->sam_ldb,
2532 mem_ctx, msg, "priorValue", &val) != 0) {
2533 return NT_STATUS_NO_MEMORY;
2536 /* set old value mtime */
2537 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2538 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
2539 return NT_STATUS_NO_MEMORY;
2542 } else {
2543 /* If the old value is not set, then migrate the
2544 * current value to the old value */
2545 const struct ldb_val *old_val;
2546 NTTIME last_set_time;
2547 struct ldb_message **res;
2548 const char *attrs[] = {
2549 "currentValue",
2550 "lastSetTime",
2551 NULL
2554 /* search for the secret record */
2555 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
2556 secret_state->secret_dn, &res, attrs);
2557 if (ret == 0) {
2558 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2561 if (ret != 1) {
2562 DEBUG(0,("Found %d records matching dn=%s\n", ret,
2563 ldb_dn_get_linearized(secret_state->secret_dn)));
2564 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2567 old_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2568 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2570 if (old_val) {
2571 /* set old value */
2572 if (samdb_msg_add_value(secret_state->sam_ldb,
2573 mem_ctx, msg, "priorValue",
2574 old_val) != 0) {
2575 return NT_STATUS_NO_MEMORY;
2577 } else {
2578 if (samdb_msg_add_delete(secret_state->sam_ldb,
2579 mem_ctx, msg, "priorValue")) {
2580 return NT_STATUS_NO_MEMORY;
2585 /* set old value mtime */
2586 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2587 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2588 mem_ctx, msg, "priorSetTime", last_set_time) != 0) {
2589 return NT_STATUS_NO_MEMORY;
2591 } else {
2592 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2593 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
2594 return NT_STATUS_NO_MEMORY;
2599 if (r->in.new_val) {
2600 /* Decrypt */
2601 crypt_secret.data = r->in.new_val->data;
2602 crypt_secret.length = r->in.new_val->size;
2604 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2605 if (!NT_STATUS_IS_OK(status)) {
2606 return status;
2609 val.data = secret.data;
2610 val.length = secret.length;
2612 /* set value */
2613 if (samdb_msg_add_value(secret_state->sam_ldb,
2614 mem_ctx, msg, "currentValue", &val) != 0) {
2615 return NT_STATUS_NO_MEMORY;
2618 /* set new value mtime */
2619 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2620 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2621 return NT_STATUS_NO_MEMORY;
2624 } else {
2625 /* NULL out the NEW value */
2626 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2627 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2628 return NT_STATUS_NO_MEMORY;
2630 if (samdb_msg_add_delete(secret_state->sam_ldb,
2631 mem_ctx, msg, "currentValue")) {
2632 return NT_STATUS_NO_MEMORY;
2636 /* modify the samdb record */
2637 ret = samdb_replace(secret_state->sam_ldb, mem_ctx, msg);
2638 if (ret != 0) {
2639 /* we really need samdb.c to return NTSTATUS */
2640 return NT_STATUS_UNSUCCESSFUL;
2643 return NT_STATUS_OK;
2648 lsa_QuerySecret
2650 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2651 struct lsa_QuerySecret *r)
2653 struct dcesrv_handle *h;
2654 struct lsa_secret_state *secret_state;
2655 struct ldb_message *msg;
2656 DATA_BLOB session_key;
2657 DATA_BLOB crypt_secret, secret;
2658 int ret;
2659 struct ldb_message **res;
2660 const char *attrs[] = {
2661 "currentValue",
2662 "priorValue",
2663 "lastSetTime",
2664 "priorSetTime",
2665 NULL
2668 NTSTATUS nt_status;
2670 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2672 /* Ensure user is permitted to read this... */
2673 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2675 case SECURITY_SYSTEM:
2676 case SECURITY_ADMINISTRATOR:
2677 break;
2678 default:
2679 /* Users and annonymous are not allowed to read secrets */
2680 return NT_STATUS_ACCESS_DENIED;
2683 secret_state = h->data;
2685 /* pull all the user attributes */
2686 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2687 secret_state->secret_dn, &res, attrs);
2688 if (ret != 1) {
2689 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2691 msg = res[0];
2693 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2694 if (!NT_STATUS_IS_OK(nt_status)) {
2695 return nt_status;
2698 if (r->in.old_val) {
2699 const struct ldb_val *prior_val;
2700 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2701 if (!r->out.old_val) {
2702 return NT_STATUS_NO_MEMORY;
2704 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
2706 if (prior_val && prior_val->length) {
2707 secret.data = prior_val->data;
2708 secret.length = prior_val->length;
2710 /* Encrypt */
2711 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2712 if (!crypt_secret.length) {
2713 return NT_STATUS_NO_MEMORY;
2715 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2716 if (!r->out.old_val->buf) {
2717 return NT_STATUS_NO_MEMORY;
2719 r->out.old_val->buf->size = crypt_secret.length;
2720 r->out.old_val->buf->length = crypt_secret.length;
2721 r->out.old_val->buf->data = crypt_secret.data;
2725 if (r->in.old_mtime) {
2726 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2727 if (!r->out.old_mtime) {
2728 return NT_STATUS_NO_MEMORY;
2730 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
2733 if (r->in.new_val) {
2734 const struct ldb_val *new_val;
2735 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2736 if (!r->out.new_val) {
2737 return NT_STATUS_NO_MEMORY;
2740 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2742 if (new_val && new_val->length) {
2743 secret.data = new_val->data;
2744 secret.length = new_val->length;
2746 /* Encrypt */
2747 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2748 if (!crypt_secret.length) {
2749 return NT_STATUS_NO_MEMORY;
2751 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2752 if (!r->out.new_val->buf) {
2753 return NT_STATUS_NO_MEMORY;
2755 r->out.new_val->buf->length = crypt_secret.length;
2756 r->out.new_val->buf->size = crypt_secret.length;
2757 r->out.new_val->buf->data = crypt_secret.data;
2761 if (r->in.new_mtime) {
2762 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2763 if (!r->out.new_mtime) {
2764 return NT_STATUS_NO_MEMORY;
2766 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2769 return NT_STATUS_OK;
2774 lsa_LookupPrivValue
2776 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
2777 TALLOC_CTX *mem_ctx,
2778 struct lsa_LookupPrivValue *r)
2780 struct dcesrv_handle *h;
2781 struct lsa_policy_state *state;
2782 int id;
2784 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2786 state = h->data;
2788 id = sec_privilege_id(r->in.name->string);
2789 if (id == -1) {
2790 return NT_STATUS_NO_SUCH_PRIVILEGE;
2793 r->out.luid->low = id;
2794 r->out.luid->high = 0;
2796 return NT_STATUS_OK;
2801 lsa_LookupPrivName
2803 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
2804 TALLOC_CTX *mem_ctx,
2805 struct lsa_LookupPrivName *r)
2807 struct dcesrv_handle *h;
2808 struct lsa_policy_state *state;
2809 struct lsa_StringLarge *name;
2810 const char *privname;
2812 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2814 state = h->data;
2816 if (r->in.luid->high != 0) {
2817 return NT_STATUS_NO_SUCH_PRIVILEGE;
2820 privname = sec_privilege_name(r->in.luid->low);
2821 if (privname == NULL) {
2822 return NT_STATUS_NO_SUCH_PRIVILEGE;
2825 name = talloc(mem_ctx, struct lsa_StringLarge);
2826 if (name == NULL) {
2827 return NT_STATUS_NO_MEMORY;
2830 name->string = privname;
2832 *r->out.name = name;
2834 return NT_STATUS_OK;
2839 lsa_LookupPrivDisplayName
2841 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
2842 TALLOC_CTX *mem_ctx,
2843 struct lsa_LookupPrivDisplayName *r)
2845 struct dcesrv_handle *h;
2846 struct lsa_policy_state *state;
2847 struct lsa_StringLarge *disp_name = NULL;
2848 int id;
2850 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2852 state = h->data;
2854 id = sec_privilege_id(r->in.name->string);
2855 if (id == -1) {
2856 return NT_STATUS_NO_SUCH_PRIVILEGE;
2859 disp_name = talloc(mem_ctx, struct lsa_StringLarge);
2860 if (disp_name == NULL) {
2861 return NT_STATUS_NO_MEMORY;
2864 disp_name->string = sec_privilege_display_name(id, &r->in.language_id);
2865 if (disp_name->string == NULL) {
2866 return NT_STATUS_INTERNAL_ERROR;
2869 *r->out.disp_name = disp_name;
2870 *r->out.returned_language_id = 0;
2872 return NT_STATUS_OK;
2877 lsa_EnumAccountsWithUserRight
2879 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
2880 TALLOC_CTX *mem_ctx,
2881 struct lsa_EnumAccountsWithUserRight *r)
2883 struct dcesrv_handle *h;
2884 struct lsa_policy_state *state;
2885 int ret, i;
2886 struct ldb_message **res;
2887 const char * const attrs[] = { "objectSid", NULL};
2888 const char *privname;
2890 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2892 state = h->data;
2894 if (r->in.name == NULL) {
2895 return NT_STATUS_NO_SUCH_PRIVILEGE;
2898 privname = r->in.name->string;
2899 if (sec_privilege_id(privname) == -1) {
2900 return NT_STATUS_NO_SUCH_PRIVILEGE;
2903 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
2904 "privilege=%s", privname);
2905 if (ret == -1) {
2906 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2908 if (ret == 0) {
2909 return NT_STATUS_NO_MORE_ENTRIES;
2912 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2913 if (r->out.sids->sids == NULL) {
2914 return NT_STATUS_NO_MEMORY;
2916 for (i=0;i<ret;i++) {
2917 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2918 res[i], "objectSid");
2919 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2921 r->out.sids->num_sids = ret;
2923 return NT_STATUS_OK;
2928 lsa_AddAccountRights
2930 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
2931 TALLOC_CTX *mem_ctx,
2932 struct lsa_AddAccountRights *r)
2934 struct dcesrv_handle *h;
2935 struct lsa_policy_state *state;
2937 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2939 state = h->data;
2941 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2942 LDB_FLAG_MOD_ADD,
2943 r->in.sid, r->in.rights);
2948 lsa_RemoveAccountRights
2950 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
2951 TALLOC_CTX *mem_ctx,
2952 struct lsa_RemoveAccountRights *r)
2954 struct dcesrv_handle *h;
2955 struct lsa_policy_state *state;
2957 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2959 state = h->data;
2961 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2962 LDB_FLAG_MOD_DELETE,
2963 r->in.sid, r->in.rights);
2968 lsa_StorePrivateData
2970 static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2971 struct lsa_StorePrivateData *r)
2973 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2978 lsa_RetrievePrivateData
2980 static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2981 struct lsa_RetrievePrivateData *r)
2983 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2988 lsa_GetUserName
2990 static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2991 struct lsa_GetUserName *r)
2993 NTSTATUS status = NT_STATUS_OK;
2994 const char *account_name;
2995 const char *authority_name;
2996 struct lsa_String *_account_name;
2997 struct lsa_String *_authority_name = NULL;
2999 /* this is what w2k3 does */
3000 r->out.account_name = r->in.account_name;
3001 r->out.authority_name = r->in.authority_name;
3003 if (r->in.account_name
3004 && *r->in.account_name
3005 /* && *(*r->in.account_name)->string */
3007 return NT_STATUS_INVALID_PARAMETER;
3010 if (r->in.authority_name
3011 && *r->in.authority_name
3012 /* && *(*r->in.authority_name)->string */
3014 return NT_STATUS_INVALID_PARAMETER;
3017 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
3018 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
3020 _account_name = talloc(mem_ctx, struct lsa_String);
3021 NT_STATUS_HAVE_NO_MEMORY(_account_name);
3022 _account_name->string = account_name;
3024 if (r->in.authority_name) {
3025 _authority_name = talloc(mem_ctx, struct lsa_String);
3026 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
3027 _authority_name->string = authority_name;
3030 *r->out.account_name = _account_name;
3031 if (r->out.authority_name) {
3032 *r->out.authority_name = _authority_name;
3035 return status;
3039 lsa_SetInfoPolicy2
3041 static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
3042 TALLOC_CTX *mem_ctx,
3043 struct lsa_SetInfoPolicy2 *r)
3045 /* need to support these */
3046 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3050 lsa_QueryDomainInformationPolicy
3052 static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
3053 TALLOC_CTX *mem_ctx,
3054 struct lsa_QueryDomainInformationPolicy *r)
3056 union lsa_DomainInformationPolicy *info;
3058 info = talloc(r->out.info, union lsa_DomainInformationPolicy);
3059 if (!info) {
3060 return NT_STATUS_NO_MEMORY;
3063 switch (r->in.level) {
3064 case LSA_DOMAIN_INFO_POLICY_EFS:
3065 talloc_free(info);
3066 *r->out.info = NULL;
3067 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3068 case LSA_DOMAIN_INFO_POLICY_KERBEROS:
3070 struct lsa_DomainInfoKerberos *k = &info->kerberos_info;
3071 struct smb_krb5_context *smb_krb5_context;
3072 int ret = smb_krb5_init_context(mem_ctx,
3073 dce_call->event_ctx,
3074 dce_call->conn->dce_ctx->lp_ctx,
3075 &smb_krb5_context);
3076 if (ret != 0) {
3077 talloc_free(info);
3078 *r->out.info = NULL;
3079 return NT_STATUS_INTERNAL_ERROR;
3081 k->enforce_restrictions = 0; /* FIXME, details missing from MS-LSAD 2.2.53 */
3082 k->service_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
3083 k->user_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
3084 k->user_tkt_renewaltime = 0; /* Need to find somewhere to store this, and query in KDC too */
3085 k->clock_skew = krb5_get_max_time_skew(smb_krb5_context->krb5_context);
3086 talloc_free(smb_krb5_context);
3087 *r->out.info = info;
3088 return NT_STATUS_OK;
3090 default:
3091 talloc_free(info);
3092 *r->out.info = NULL;
3093 return NT_STATUS_INVALID_INFO_CLASS;
3098 lsa_SetDomInfoPolicy
3100 static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
3101 TALLOC_CTX *mem_ctx,
3102 struct lsa_SetDomainInformationPolicy *r)
3104 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3108 lsa_TestCall
3110 static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
3111 TALLOC_CTX *mem_ctx,
3112 struct lsa_TestCall *r)
3114 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3118 lsa_CREDRWRITE
3120 static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3121 struct lsa_CREDRWRITE *r)
3123 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3128 lsa_CREDRREAD
3130 static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3131 struct lsa_CREDRREAD *r)
3133 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3138 lsa_CREDRENUMERATE
3140 static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3141 struct lsa_CREDRENUMERATE *r)
3143 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3148 lsa_CREDRWRITEDOMAINCREDENTIALS
3150 static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3151 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3153 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3158 lsa_CREDRREADDOMAINCREDENTIALS
3160 static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3161 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3163 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3168 lsa_CREDRDELETE
3170 static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3171 struct lsa_CREDRDELETE *r)
3173 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3178 lsa_CREDRGETTARGETINFO
3180 static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3181 struct lsa_CREDRGETTARGETINFO *r)
3183 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3188 lsa_CREDRPROFILELOADED
3190 static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3191 struct lsa_CREDRPROFILELOADED *r)
3193 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3198 lsa_CREDRGETSESSIONTYPES
3200 static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3201 struct lsa_CREDRGETSESSIONTYPES *r)
3203 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3208 lsa_LSARREGISTERAUDITEVENT
3210 static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3211 struct lsa_LSARREGISTERAUDITEVENT *r)
3213 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3218 lsa_LSARGENAUDITEVENT
3220 static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3221 struct lsa_LSARGENAUDITEVENT *r)
3223 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3228 lsa_LSARUNREGISTERAUDITEVENT
3230 static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3231 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3233 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3238 lsa_lsaRQueryForestTrustInformation
3240 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3241 struct lsa_lsaRQueryForestTrustInformation *r)
3243 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3248 lsa_LSARSETFORESTTRUSTINFORMATION
3250 static NTSTATUS dcesrv_lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3251 struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
3253 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3258 lsa_CREDRRENAME
3260 static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3261 struct lsa_CREDRRENAME *r)
3263 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3269 lsa_LSAROPENPOLICYSCE
3271 static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3272 struct lsa_LSAROPENPOLICYSCE *r)
3274 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3279 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
3281 static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3282 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
3284 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3289 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
3291 static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3292 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
3294 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3299 lsa_LSARADTREPORTSECURITYEVENT
3301 static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3302 struct lsa_LSARADTREPORTSECURITYEVENT *r)
3304 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3308 /* include the generated boilerplate */
3309 #include "librpc/gen_ndr/ndr_lsa_s.c"
3313 /*****************************************
3314 NOTE! The remaining calls below were
3315 removed in w2k3, so the DCESRV_FAULT()
3316 replies are the correct implementation. Do
3317 not try and fill these in with anything else
3318 ******************************************/
3321 dssetup_DsRoleDnsNameToFlatName
3323 static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3324 struct dssetup_DsRoleDnsNameToFlatName *r)
3326 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3331 dssetup_DsRoleDcAsDc
3333 static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3334 struct dssetup_DsRoleDcAsDc *r)
3336 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3341 dssetup_DsRoleDcAsReplica
3343 static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3344 struct dssetup_DsRoleDcAsReplica *r)
3346 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3351 dssetup_DsRoleDemoteDc
3353 static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3354 struct dssetup_DsRoleDemoteDc *r)
3356 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3361 dssetup_DsRoleGetDcOperationProgress
3363 static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3364 struct dssetup_DsRoleGetDcOperationProgress *r)
3366 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3371 dssetup_DsRoleGetDcOperationResults
3373 static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3374 struct dssetup_DsRoleGetDcOperationResults *r)
3376 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3381 dssetup_DsRoleCancel
3383 static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3384 struct dssetup_DsRoleCancel *r)
3386 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3391 dssetup_DsRoleServerSaveStateForUpgrade
3393 static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3394 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
3396 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3401 dssetup_DsRoleUpgradeDownlevelServer
3403 static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3404 struct dssetup_DsRoleUpgradeDownlevelServer *r)
3406 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3411 dssetup_DsRoleAbortDownlevelServerUpgrade
3413 static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3414 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
3416 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3420 /* include the generated boilerplate */
3421 #include "librpc/gen_ndr/ndr_dssetup_s.c"
3423 NTSTATUS dcerpc_server_lsa_init(void)
3425 NTSTATUS ret;
3427 ret = dcerpc_server_dssetup_init();
3428 if (!NT_STATUS_IS_OK(ret)) {
3429 return ret;
3431 ret = dcerpc_server_lsarpc_init();
3432 if (!NT_STATUS_IS_OK(ret)) {
3433 return ret;
3435 return ret;