s4:lsa Functions to set Domain Trust Information
[Samba/ekacnet.git] / source4 / rpc_server / lsa / dcesrv_lsa.c
blobc2805c26e580a275221ab6ff4e70213c46f031ee
1 /* need access mask/acl implementation */
3 /*
4 Unix SMB/CIFS implementation.
6 endpoint server for the lsarpc pipe
8 Copyright (C) Andrew Tridgell 2004
9 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2008
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "rpc_server/lsa/lsa.h"
26 #include "system/kerberos.h"
27 #include "auth/kerberos/kerberos.h"
28 #include "librpc/gen_ndr/ndr_drsblobs.h"
29 #include "librpc/gen_ndr/ndr_lsa.h"
30 #include "../lib/crypto/crypto.h"
31 #include "lib/util/tsort.h"
34 this type allows us to distinguish handle types
38 state associated with a lsa_OpenAccount() operation
40 struct lsa_account_state {
41 struct lsa_policy_state *policy;
42 uint32_t access_mask;
43 struct dom_sid *account_sid;
48 state associated with a lsa_OpenSecret() operation
50 struct lsa_secret_state {
51 struct lsa_policy_state *policy;
52 uint32_t access_mask;
53 struct ldb_dn *secret_dn;
54 struct ldb_context *sam_ldb;
55 bool global;
59 state associated with a lsa_OpenTrustedDomain() operation
61 struct lsa_trusted_domain_state {
62 struct lsa_policy_state *policy;
63 uint32_t access_mask;
64 struct ldb_dn *trusted_domain_dn;
65 struct ldb_dn *trusted_domain_user_dn;
69 this is based on the samba3 function make_lsa_object_sd()
70 It uses the same logic, but with samba4 helper functions
72 static NTSTATUS dcesrv_build_lsa_sd(TALLOC_CTX *mem_ctx,
73 struct security_descriptor **sd,
74 struct dom_sid *sid,
75 uint32_t sid_access)
77 NTSTATUS status;
78 uint32_t rid;
79 struct dom_sid *domain_sid, *domain_admins_sid;
80 const char *domain_admins_sid_str, *sidstr;
81 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
83 status = dom_sid_split_rid(tmp_ctx, sid, &domain_sid, &rid);
84 NT_STATUS_NOT_OK_RETURN_AND_FREE(status, tmp_ctx);
86 domain_admins_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ADMINS);
87 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(domain_admins_sid, tmp_ctx);
89 domain_admins_sid_str = dom_sid_string(tmp_ctx, domain_admins_sid);
90 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(domain_admins_sid_str, tmp_ctx);
92 sidstr = dom_sid_string(tmp_ctx, sid);
93 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidstr, tmp_ctx);
95 *sd = security_descriptor_dacl_create(mem_ctx,
96 0, sidstr, NULL,
98 SID_WORLD,
99 SEC_ACE_TYPE_ACCESS_ALLOWED,
100 SEC_GENERIC_EXECUTE | SEC_GENERIC_READ, 0,
102 SID_BUILTIN_ADMINISTRATORS,
103 SEC_ACE_TYPE_ACCESS_ALLOWED,
104 SEC_GENERIC_ALL, 0,
106 SID_BUILTIN_ACCOUNT_OPERATORS,
107 SEC_ACE_TYPE_ACCESS_ALLOWED,
108 SEC_GENERIC_ALL, 0,
110 domain_admins_sid_str,
111 SEC_ACE_TYPE_ACCESS_ALLOWED,
112 SEC_GENERIC_ALL, 0,
114 sidstr,
115 SEC_ACE_TYPE_ACCESS_ALLOWED,
116 sid_access, 0,
118 NULL);
119 talloc_free(tmp_ctx);
121 NT_STATUS_HAVE_NO_MEMORY(*sd);
123 return NT_STATUS_OK;
127 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
128 TALLOC_CTX *mem_ctx,
129 struct lsa_EnumAccountRights *r);
131 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
132 TALLOC_CTX *mem_ctx,
133 struct lsa_policy_state *state,
134 int ldb_flag,
135 struct dom_sid *sid,
136 const struct lsa_RightSet *rights);
139 lsa_Close
141 static NTSTATUS dcesrv_lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
142 struct lsa_Close *r)
144 struct dcesrv_handle *h;
146 *r->out.handle = *r->in.handle;
148 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
150 talloc_free(h);
152 ZERO_STRUCTP(r->out.handle);
154 return NT_STATUS_OK;
159 lsa_Delete
161 static NTSTATUS dcesrv_lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
162 struct lsa_Delete *r)
164 return NT_STATUS_NOT_SUPPORTED;
169 lsa_DeleteObject
171 static NTSTATUS dcesrv_lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
172 struct lsa_DeleteObject *r)
174 struct dcesrv_handle *h;
175 int ret;
177 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
179 if (h->wire_handle.handle_type == LSA_HANDLE_SECRET) {
180 struct lsa_secret_state *secret_state = h->data;
182 /* Ensure user is permitted to delete this... */
183 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
185 case SECURITY_SYSTEM:
186 case SECURITY_ADMINISTRATOR:
187 break;
188 default:
189 /* Users and annonymous are not allowed delete things */
190 return NT_STATUS_ACCESS_DENIED;
193 ret = ldb_delete(secret_state->sam_ldb,
194 secret_state->secret_dn);
195 talloc_free(h);
196 if (ret != LDB_SUCCESS) {
197 return NT_STATUS_INVALID_HANDLE;
200 ZERO_STRUCTP(r->out.handle);
202 return NT_STATUS_OK;
203 } else if (h->wire_handle.handle_type == LSA_HANDLE_TRUSTED_DOMAIN) {
204 struct lsa_trusted_domain_state *trusted_domain_state =
205 talloc_get_type(h->data, struct lsa_trusted_domain_state);
206 ret = ldb_transaction_start(trusted_domain_state->policy->sam_ldb);
207 if (ret != LDB_SUCCESS) {
208 return NT_STATUS_INTERNAL_DB_CORRUPTION;
211 ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
212 trusted_domain_state->trusted_domain_dn);
213 if (ret != LDB_SUCCESS) {
214 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
215 return NT_STATUS_INVALID_HANDLE;
218 if (trusted_domain_state->trusted_domain_user_dn) {
219 ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
220 trusted_domain_state->trusted_domain_user_dn);
221 if (ret != LDB_SUCCESS) {
222 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
223 return NT_STATUS_INVALID_HANDLE;
227 ret = ldb_transaction_commit(trusted_domain_state->policy->sam_ldb);
228 if (ret != LDB_SUCCESS) {
229 return NT_STATUS_INTERNAL_DB_CORRUPTION;
231 talloc_free(h);
232 ZERO_STRUCTP(r->out.handle);
234 return NT_STATUS_OK;
235 } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
236 struct lsa_RightSet *rights;
237 struct lsa_account_state *astate;
238 struct lsa_EnumAccountRights r2;
239 NTSTATUS status;
241 rights = talloc(mem_ctx, struct lsa_RightSet);
243 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
245 astate = h->data;
247 r2.in.handle = &astate->policy->handle->wire_handle;
248 r2.in.sid = astate->account_sid;
249 r2.out.rights = rights;
251 /* dcesrv_lsa_EnumAccountRights takes a LSA_HANDLE_POLICY,
252 but we have a LSA_HANDLE_ACCOUNT here, so this call
253 will always fail */
254 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
255 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
256 return NT_STATUS_OK;
259 if (!NT_STATUS_IS_OK(status)) {
260 return status;
263 status = dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
264 LDB_FLAG_MOD_DELETE, astate->account_sid,
265 r2.out.rights);
266 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
267 return NT_STATUS_OK;
270 if (!NT_STATUS_IS_OK(status)) {
271 return status;
274 ZERO_STRUCTP(r->out.handle);
277 return NT_STATUS_INVALID_HANDLE;
282 lsa_EnumPrivs
284 static NTSTATUS dcesrv_lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
285 struct lsa_EnumPrivs *r)
287 struct dcesrv_handle *h;
288 struct lsa_policy_state *state;
289 uint32_t i;
290 const char *privname;
292 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
294 state = h->data;
296 i = *r->in.resume_handle;
297 if (i == 0) i = 1;
299 while ((privname = sec_privilege_name(i)) &&
300 r->out.privs->count < r->in.max_count) {
301 struct lsa_PrivEntry *e;
303 r->out.privs->privs = talloc_realloc(r->out.privs,
304 r->out.privs->privs,
305 struct lsa_PrivEntry,
306 r->out.privs->count+1);
307 if (r->out.privs->privs == NULL) {
308 return NT_STATUS_NO_MEMORY;
310 e = &r->out.privs->privs[r->out.privs->count];
311 e->luid.low = i;
312 e->luid.high = 0;
313 e->name.string = privname;
314 r->out.privs->count++;
315 i++;
318 *r->out.resume_handle = i;
320 return NT_STATUS_OK;
325 lsa_QuerySecObj
327 static NTSTATUS dcesrv_lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
328 struct lsa_QuerySecurity *r)
330 struct dcesrv_handle *h;
331 struct security_descriptor *sd;
332 NTSTATUS status;
333 struct dom_sid *sid;
335 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
337 sid = dce_call->conn->auth_state.session_info->security_token->user_sid;
339 if (h->wire_handle.handle_type == LSA_HANDLE_POLICY) {
340 status = dcesrv_build_lsa_sd(mem_ctx, &sd, sid, 0);
341 } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
342 status = dcesrv_build_lsa_sd(mem_ctx, &sd, sid,
343 LSA_ACCOUNT_ALL_ACCESS);
344 } else {
345 return NT_STATUS_INVALID_HANDLE;
347 NT_STATUS_NOT_OK_RETURN(status);
349 (*r->out.sdbuf) = talloc(mem_ctx, struct sec_desc_buf);
350 NT_STATUS_HAVE_NO_MEMORY(*r->out.sdbuf);
352 (*r->out.sdbuf)->sd = sd;
354 return NT_STATUS_OK;
359 lsa_SetSecObj
361 static NTSTATUS dcesrv_lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
362 struct lsa_SetSecObj *r)
364 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
369 lsa_ChangePassword
371 static NTSTATUS dcesrv_lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
372 struct lsa_ChangePassword *r)
374 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
378 dssetup_DsRoleGetPrimaryDomainInformation
380 This is not an LSA call, but is the only call left on the DSSETUP
381 pipe (after the pipe was truncated), and needs lsa_get_policy_state
383 static WERROR dcesrv_dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state *dce_call,
384 TALLOC_CTX *mem_ctx,
385 struct dssetup_DsRoleGetPrimaryDomainInformation *r)
387 union dssetup_DsRoleInfo *info;
389 info = talloc(mem_ctx, union dssetup_DsRoleInfo);
390 W_ERROR_HAVE_NO_MEMORY(info);
392 switch (r->in.level) {
393 case DS_ROLE_BASIC_INFORMATION:
395 enum dssetup_DsRole role = DS_ROLE_STANDALONE_SERVER;
396 uint32_t flags = 0;
397 const char *domain = NULL;
398 const char *dns_domain = NULL;
399 const char *forest = NULL;
400 struct GUID domain_guid;
401 struct lsa_policy_state *state;
403 NTSTATUS status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
404 if (!NT_STATUS_IS_OK(status)) {
405 return ntstatus_to_werror(status);
408 ZERO_STRUCT(domain_guid);
410 switch (lp_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
411 case ROLE_STANDALONE:
412 role = DS_ROLE_STANDALONE_SERVER;
413 break;
414 case ROLE_DOMAIN_MEMBER:
415 role = DS_ROLE_MEMBER_SERVER;
416 break;
417 case ROLE_DOMAIN_CONTROLLER:
418 if (samdb_is_pdc(state->sam_ldb)) {
419 role = DS_ROLE_PRIMARY_DC;
420 } else {
421 role = DS_ROLE_BACKUP_DC;
423 break;
426 switch (lp_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
427 case ROLE_STANDALONE:
428 domain = talloc_strdup(mem_ctx, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx));
429 W_ERROR_HAVE_NO_MEMORY(domain);
430 break;
431 case ROLE_DOMAIN_MEMBER:
432 domain = talloc_strdup(mem_ctx, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx));
433 W_ERROR_HAVE_NO_MEMORY(domain);
434 /* TODO: what is with dns_domain and forest and guid? */
435 break;
436 case ROLE_DOMAIN_CONTROLLER:
437 flags = DS_ROLE_PRIMARY_DS_RUNNING;
439 if (state->mixed_domain == 1) {
440 flags |= DS_ROLE_PRIMARY_DS_MIXED_MODE;
443 domain = state->domain_name;
444 dns_domain = state->domain_dns;
445 forest = state->forest_dns;
447 domain_guid = state->domain_guid;
448 flags |= DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT;
449 break;
452 info->basic.role = role;
453 info->basic.flags = flags;
454 info->basic.domain = domain;
455 info->basic.dns_domain = dns_domain;
456 info->basic.forest = forest;
457 info->basic.domain_guid = domain_guid;
459 r->out.info = info;
460 return WERR_OK;
462 case DS_ROLE_UPGRADE_STATUS:
464 info->upgrade.upgrading = DS_ROLE_NOT_UPGRADING;
465 info->upgrade.previous_role = DS_ROLE_PREVIOUS_UNKNOWN;
467 r->out.info = info;
468 return WERR_OK;
470 case DS_ROLE_OP_STATUS:
472 info->opstatus.status = DS_ROLE_OP_IDLE;
474 r->out.info = info;
475 return WERR_OK;
477 default:
478 return WERR_INVALID_PARAM;
481 return WERR_INVALID_PARAM;
485 fill in the AccountDomain info
487 static NTSTATUS dcesrv_lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
488 struct lsa_DomainInfo *info)
490 info->name.string = state->domain_name;
491 info->sid = state->domain_sid;
493 return NT_STATUS_OK;
497 fill in the DNS domain info
499 static NTSTATUS dcesrv_lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
500 struct lsa_DnsDomainInfo *info)
502 info->name.string = state->domain_name;
503 info->sid = state->domain_sid;
504 info->dns_domain.string = state->domain_dns;
505 info->dns_forest.string = state->forest_dns;
506 info->domain_guid = state->domain_guid;
508 return NT_STATUS_OK;
512 lsa_QueryInfoPolicy2
514 static NTSTATUS dcesrv_lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
515 struct lsa_QueryInfoPolicy2 *r)
517 struct lsa_policy_state *state;
518 struct dcesrv_handle *h;
519 union lsa_PolicyInformation *info;
521 *r->out.info = NULL;
523 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
525 state = h->data;
527 info = talloc_zero(mem_ctx, union lsa_PolicyInformation);
528 if (!info) {
529 return NT_STATUS_NO_MEMORY;
531 *r->out.info = info;
533 switch (r->in.level) {
534 case LSA_POLICY_INFO_AUDIT_LOG:
535 /* we don't need to fill in any of this */
536 ZERO_STRUCT(info->audit_log);
537 return NT_STATUS_OK;
538 case LSA_POLICY_INFO_AUDIT_EVENTS:
539 /* we don't need to fill in any of this */
540 ZERO_STRUCT(info->audit_events);
541 return NT_STATUS_OK;
542 case LSA_POLICY_INFO_PD:
543 /* we don't need to fill in any of this */
544 ZERO_STRUCT(info->pd);
545 return NT_STATUS_OK;
547 case LSA_POLICY_INFO_DOMAIN:
548 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->domain);
549 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
550 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->account_domain);
551 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
552 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->l_account_domain);
554 case LSA_POLICY_INFO_ROLE:
555 info->role.role = LSA_ROLE_PRIMARY;
556 return NT_STATUS_OK;
558 case LSA_POLICY_INFO_DNS:
559 case LSA_POLICY_INFO_DNS_INT:
560 return dcesrv_lsa_info_DNS(state, mem_ctx, &info->dns);
562 case LSA_POLICY_INFO_REPLICA:
563 ZERO_STRUCT(info->replica);
564 return NT_STATUS_OK;
566 case LSA_POLICY_INFO_QUOTA:
567 ZERO_STRUCT(info->quota);
568 return NT_STATUS_OK;
570 case LSA_POLICY_INFO_MOD:
571 case LSA_POLICY_INFO_AUDIT_FULL_SET:
572 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
573 /* windows gives INVALID_PARAMETER */
574 *r->out.info = NULL;
575 return NT_STATUS_INVALID_PARAMETER;
578 *r->out.info = NULL;
579 return NT_STATUS_INVALID_INFO_CLASS;
583 lsa_QueryInfoPolicy
585 static NTSTATUS dcesrv_lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
586 struct lsa_QueryInfoPolicy *r)
588 struct lsa_QueryInfoPolicy2 r2;
589 NTSTATUS status;
591 ZERO_STRUCT(r2);
593 r2.in.handle = r->in.handle;
594 r2.in.level = r->in.level;
595 r2.out.info = r->out.info;
597 status = dcesrv_lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
599 return status;
603 lsa_SetInfoPolicy
605 static NTSTATUS dcesrv_lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
606 struct lsa_SetInfoPolicy *r)
608 /* need to support this */
609 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
614 lsa_ClearAuditLog
616 static NTSTATUS dcesrv_lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
617 struct lsa_ClearAuditLog *r)
619 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
624 lsa_CreateAccount
626 This call does not seem to have any long-term effects, hence no database operations
628 we need to talk to the MS product group to find out what this account database means!
630 answer is that the lsa database is totally separate from the SAM and
631 ldap databases. We are going to need a separate ldb to store these
632 accounts. The SIDs on this account bear no relation to the SIDs in
635 static NTSTATUS dcesrv_lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
636 struct lsa_CreateAccount *r)
638 struct lsa_account_state *astate;
640 struct lsa_policy_state *state;
641 struct dcesrv_handle *h, *ah;
643 ZERO_STRUCTP(r->out.acct_handle);
645 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
647 state = h->data;
649 astate = talloc(dce_call->conn, struct lsa_account_state);
650 if (astate == NULL) {
651 return NT_STATUS_NO_MEMORY;
654 astate->account_sid = dom_sid_dup(astate, r->in.sid);
655 if (astate->account_sid == NULL) {
656 talloc_free(astate);
657 return NT_STATUS_NO_MEMORY;
660 astate->policy = talloc_reference(astate, state);
661 astate->access_mask = r->in.access_mask;
663 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
664 if (!ah) {
665 talloc_free(astate);
666 return NT_STATUS_NO_MEMORY;
669 ah->data = talloc_steal(ah, astate);
671 *r->out.acct_handle = ah->wire_handle;
673 return NT_STATUS_OK;
678 lsa_EnumAccounts
680 static NTSTATUS dcesrv_lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
681 struct lsa_EnumAccounts *r)
683 struct dcesrv_handle *h;
684 struct lsa_policy_state *state;
685 int ret;
686 struct ldb_message **res;
687 const char * const attrs[] = { "objectSid", NULL};
688 uint32_t count, i;
690 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
692 state = h->data;
694 /* NOTE: This call must only return accounts that have at least
695 one privilege set
697 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
698 "(&(objectSid=*)(privilege=*))");
699 if (ret < 0) {
700 return NT_STATUS_INTERNAL_DB_CORRUPTION;
703 if (*r->in.resume_handle >= ret) {
704 return NT_STATUS_NO_MORE_ENTRIES;
707 count = ret - *r->in.resume_handle;
708 if (count > r->in.num_entries) {
709 count = r->in.num_entries;
712 if (count == 0) {
713 return NT_STATUS_NO_MORE_ENTRIES;
716 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, count);
717 if (r->out.sids->sids == NULL) {
718 return NT_STATUS_NO_MEMORY;
721 for (i=0;i<count;i++) {
722 r->out.sids->sids[i].sid =
723 samdb_result_dom_sid(r->out.sids->sids,
724 res[i + *r->in.resume_handle],
725 "objectSid");
726 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
729 r->out.sids->num_sids = count;
730 *r->out.resume_handle = count + *r->in.resume_handle;
732 return NT_STATUS_OK;
736 /* This decrypts and returns Trusted Domain Auth Information Internal data */
737 static NTSTATUS get_trustdom_auth_blob(struct dcesrv_call_state *dce_call,
738 TALLOC_CTX *mem_ctx, DATA_BLOB *auth_blob,
739 struct trustDomainPasswords *auth_struct)
741 DATA_BLOB session_key = data_blob(NULL, 0);
742 enum ndr_err_code ndr_err;
743 NTSTATUS nt_status;
745 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
746 if (!NT_STATUS_IS_OK(nt_status)) {
747 return nt_status;
750 arcfour_crypt_blob(auth_blob->data, auth_blob->length, &session_key);
751 ndr_err = ndr_pull_struct_blob(auth_blob, mem_ctx,
752 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
753 auth_struct,
754 (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
755 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
756 return NT_STATUS_INVALID_PARAMETER;
759 return NT_STATUS_OK;
762 static NTSTATUS get_trustauth_inout_blob(struct dcesrv_call_state *dce_call,
763 TALLOC_CTX *mem_ctx,
764 struct trustCurrentPasswords *iopw,
765 DATA_BLOB *trustauth_blob)
767 uint32_t i;
768 struct trustAuthInOutBlob ioblob;
769 enum ndr_err_code ndr_err;
771 ioblob.count = iopw->count;
772 ioblob.current = talloc(mem_ctx,
773 struct AuthenticationInformationArray);
774 if (!ioblob.current) {
775 return NT_STATUS_NO_MEMORY;
778 ioblob.current->array = *iopw->current;
779 if (!ioblob.current->array) {
780 return NT_STATUS_NO_MEMORY;
783 ioblob.previous = talloc(mem_ctx,
784 struct AuthenticationInformationArray);
785 if (!ioblob.previous) {
786 return NT_STATUS_NO_MEMORY;
788 ioblob.previous->array = talloc_array(mem_ctx,
789 struct AuthenticationInformation,
790 ioblob.count);
791 if (!ioblob.previous->array) {
792 return NT_STATUS_NO_MEMORY;
795 for (i = 0; i < ioblob.count; i++) {
796 ioblob.previous->array[i].LastUpdateTime = 0;
797 ioblob.previous->array[i].AuthType = 0;
799 ndr_err = ndr_push_struct_blob(trustauth_blob, mem_ctx,
800 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
801 &ioblob,
802 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
803 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
804 return NT_STATUS_INVALID_PARAMETER;
807 return NT_STATUS_OK;
810 static NTSTATUS add_trust_user(TALLOC_CTX *mem_ctx,
811 struct ldb_context *sam_ldb,
812 struct ldb_dn *base_dn,
813 const char *netbios_name,
814 struct trustCurrentPasswords *in,
815 struct ldb_dn **user_dn)
817 struct ldb_message *msg;
818 struct ldb_dn *dn;
819 uint32_t i;
820 int ret;
822 dn = ldb_dn_copy(mem_ctx, base_dn);
823 if (!dn) {
824 return NT_STATUS_NO_MEMORY;
826 if (!ldb_dn_add_child_fmt(dn, "cn=%s$,cn=users", netbios_name)) {
827 return NT_STATUS_NO_MEMORY;
830 msg = ldb_msg_new(mem_ctx);
831 if (!msg) {
832 return NT_STATUS_NO_MEMORY;
834 msg->dn = dn;
836 ret = ldb_msg_add_string(msg, "objectClass", "user");
837 if (ret != LDB_SUCCESS) {
838 return NT_STATUS_NO_MEMORY;
841 ret = ldb_msg_add_fmt(msg, "samAccountName", "%s$", netbios_name);
842 if (ret != LDB_SUCCESS) {
843 return NT_STATUS_NO_MEMORY;
846 ret = ldb_msg_add_fmt(msg, "userAccountControl", "%u",
847 UF_INTERDOMAIN_TRUST_ACCOUNT);
848 if (ret != LDB_SUCCESS) {
849 return NT_STATUS_NO_MEMORY;
852 for (i = 0; i < in->count; i++) {
853 const char *attribute;
854 struct ldb_val v;
855 switch (in->current[i]->AuthType) {
856 case TRUST_AUTH_TYPE_NT4OWF:
857 attribute = "unicodePwd";
858 v.data = (uint8_t *)&in->current[i]->AuthInfo.nt4owf.password;
859 v.length = 16;
860 break;
861 case TRUST_AUTH_TYPE_CLEAR:
862 attribute = "clearTextPassword";
863 v.data = in->current[i]->AuthInfo.clear.password;
864 v.length = in->current[i]->AuthInfo.clear.size;
865 break;
866 default:
867 continue;
870 ret = ldb_msg_add_value(msg, attribute, &v, NULL);
871 if (ret != LDB_SUCCESS) {
872 return NT_STATUS_NO_MEMORY;
876 /* create the trusted_domain user account */
877 ret = ldb_add(sam_ldb, msg);
878 if (ret != LDB_SUCCESS) {
879 DEBUG(0,("Failed to create user record %s: %s\n",
880 ldb_dn_get_linearized(msg->dn),
881 ldb_errstring(sam_ldb)));
883 switch (ret) {
884 case LDB_ERR_ENTRY_ALREADY_EXISTS:
885 return NT_STATUS_DOMAIN_EXISTS;
886 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
887 return NT_STATUS_ACCESS_DENIED;
888 default:
889 return NT_STATUS_INTERNAL_DB_CORRUPTION;
893 if (user_dn) {
894 *user_dn = dn;
896 return NT_STATUS_OK;
900 lsa_CreateTrustedDomainEx2
902 static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dce_call,
903 TALLOC_CTX *mem_ctx,
904 struct lsa_CreateTrustedDomainEx2 *r,
905 int op)
907 struct dcesrv_handle *policy_handle;
908 struct lsa_policy_state *policy_state;
909 struct lsa_trusted_domain_state *trusted_domain_state;
910 struct dcesrv_handle *handle;
911 struct ldb_message **msgs, *msg;
912 const char *attrs[] = {
913 NULL
915 const char *netbios_name;
916 const char *dns_name;
917 const char *name;
918 DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob;
919 struct trustDomainPasswords auth_struct;
920 int ret;
921 NTSTATUS nt_status;
922 struct ldb_context *sam_ldb;
924 DCESRV_PULL_HANDLE(policy_handle, r->in.policy_handle, LSA_HANDLE_POLICY);
925 ZERO_STRUCTP(r->out.trustdom_handle);
927 policy_state = policy_handle->data;
928 sam_ldb = policy_state->sam_ldb;
930 netbios_name = r->in.info->netbios_name.string;
931 if (!netbios_name) {
932 return NT_STATUS_INVALID_PARAMETER;
935 dns_name = r->in.info->domain_name.string;
937 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
938 if (!trusted_domain_state) {
939 return NT_STATUS_NO_MEMORY;
941 trusted_domain_state->policy = policy_state;
943 if (strcasecmp(netbios_name, "BUILTIN") == 0
944 || (dns_name && strcasecmp(dns_name, "BUILTIN") == 0)
945 || (dom_sid_in_domain(policy_state->builtin_sid, r->in.info->sid))) {
946 return NT_STATUS_INVALID_PARAMETER;
949 if (strcasecmp(netbios_name, policy_state->domain_name) == 0
950 || strcasecmp(netbios_name, policy_state->domain_dns) == 0
951 || (dns_name && strcasecmp(dns_name, policy_state->domain_dns) == 0)
952 || (dns_name && strcasecmp(dns_name, policy_state->domain_name) == 0)
953 || (dom_sid_equal(policy_state->domain_sid, r->in.info->sid))) {
954 return NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED;
957 /* While this is a REF pointer, some of the functions that wrap this don't provide this */
958 if (op == NDR_LSA_CREATETRUSTEDDOMAIN) {
959 /* No secrets are created at this time, for this function */
960 auth_struct.outgoing.count = 0;
961 auth_struct.incoming.count = 0;
962 } else {
963 auth_blob = data_blob_const(r->in.auth_info->auth_blob.data,
964 r->in.auth_info->auth_blob.size);
965 nt_status = get_trustdom_auth_blob(dce_call, mem_ctx,
966 &auth_blob, &auth_struct);
967 if (!NT_STATUS_IS_OK(nt_status)) {
968 return nt_status;
971 if (op == NDR_LSA_CREATETRUSTEDDOMAINEX) {
972 if (auth_struct.incoming.count > 1) {
973 return NT_STATUS_INVALID_PARAMETER;
978 if (auth_struct.incoming.count) {
979 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
980 &auth_struct.incoming,
981 &trustAuthIncoming);
982 if (!NT_STATUS_IS_OK(nt_status)) {
983 return nt_status;
985 } else {
986 trustAuthIncoming = data_blob(NULL, 0);
989 if (auth_struct.outgoing.count) {
990 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
991 &auth_struct.outgoing,
992 &trustAuthOutgoing);
993 if (!NT_STATUS_IS_OK(nt_status)) {
994 return nt_status;
996 } else {
997 trustAuthOutgoing = data_blob(NULL, 0);
1000 ret = ldb_transaction_start(sam_ldb);
1001 if (ret != LDB_SUCCESS) {
1002 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1005 if (dns_name) {
1006 char *dns_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
1007 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
1008 /* search for the trusted_domain record */
1009 ret = gendb_search(sam_ldb,
1010 mem_ctx, policy_state->system_dn, &msgs, attrs,
1011 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s)(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))",
1012 dns_encoded, dns_encoded, dns_encoded, netbios_encoded, netbios_encoded, netbios_encoded);
1013 if (ret > 0) {
1014 ldb_transaction_cancel(sam_ldb);
1015 return NT_STATUS_OBJECT_NAME_COLLISION;
1017 } else {
1018 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
1019 /* search for the trusted_domain record */
1020 ret = gendb_search(sam_ldb,
1021 mem_ctx, policy_state->system_dn, &msgs, attrs,
1022 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))",
1023 netbios_encoded, netbios_encoded, netbios_encoded);
1024 if (ret > 0) {
1025 ldb_transaction_cancel(sam_ldb);
1026 return NT_STATUS_OBJECT_NAME_COLLISION;
1030 if (ret < 0 ) {
1031 ldb_transaction_cancel(sam_ldb);
1032 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1035 name = dns_name ? dns_name : netbios_name;
1037 msg = ldb_msg_new(mem_ctx);
1038 if (msg == NULL) {
1039 return NT_STATUS_NO_MEMORY;
1042 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
1043 if ( ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name)) {
1044 ldb_transaction_cancel(sam_ldb);
1045 return NT_STATUS_NO_MEMORY;
1048 samdb_msg_add_string(sam_ldb, mem_ctx, msg, "flatname", netbios_name);
1050 if (r->in.info->sid) {
1051 ret = samdb_msg_add_dom_sid(sam_ldb, mem_ctx, msg, "securityIdentifier", r->in.info->sid);
1052 if (ret != LDB_SUCCESS) {
1053 ldb_transaction_cancel(sam_ldb);
1054 return NT_STATUS_INVALID_PARAMETER;
1058 samdb_msg_add_string(sam_ldb, mem_ctx, msg, "objectClass", "trustedDomain");
1060 samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustType", r->in.info->trust_type);
1062 samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustAttributes", r->in.info->trust_attributes);
1064 samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustDirection", r->in.info->trust_direction);
1066 if (dns_name) {
1067 samdb_msg_add_string(sam_ldb, mem_ctx, msg, "trustPartner", dns_name);
1070 if (trustAuthIncoming.data) {
1071 ret = ldb_msg_add_value(msg, "trustAuthIncoming", &trustAuthIncoming, NULL);
1072 if (ret != LDB_SUCCESS) {
1073 ldb_transaction_cancel(sam_ldb);
1074 return NT_STATUS_NO_MEMORY;
1077 if (trustAuthOutgoing.data) {
1078 ret = ldb_msg_add_value(msg, "trustAuthOutgoing", &trustAuthOutgoing, NULL);
1079 if (ret != LDB_SUCCESS) {
1080 ldb_transaction_cancel(sam_ldb);
1081 return NT_STATUS_NO_MEMORY;
1085 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
1087 /* create the trusted_domain */
1088 ret = ldb_add(sam_ldb, msg);
1089 switch (ret) {
1090 case LDB_SUCCESS:
1091 break;
1092 case LDB_ERR_ENTRY_ALREADY_EXISTS:
1093 ldb_transaction_cancel(sam_ldb);
1094 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
1095 ldb_dn_get_linearized(msg->dn),
1096 ldb_errstring(sam_ldb)));
1097 return NT_STATUS_DOMAIN_EXISTS;
1098 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1099 ldb_transaction_cancel(sam_ldb);
1100 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
1101 ldb_dn_get_linearized(msg->dn),
1102 ldb_errstring(sam_ldb)));
1103 return NT_STATUS_ACCESS_DENIED;
1104 default:
1105 ldb_transaction_cancel(sam_ldb);
1106 DEBUG(0,("Failed to create user record %s: %s\n",
1107 ldb_dn_get_linearized(msg->dn),
1108 ldb_errstring(sam_ldb)));
1109 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1112 if (r->in.info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1113 struct ldb_dn *user_dn;
1114 /* Inbound trusts must also create a cn=users object to match */
1115 nt_status = add_trust_user(mem_ctx, sam_ldb,
1116 policy_state->domain_dn,
1117 netbios_name,
1118 &auth_struct.incoming,
1119 &user_dn);
1120 if (!NT_STATUS_IS_OK(nt_status)) {
1121 ldb_transaction_cancel(sam_ldb);
1122 return nt_status;
1125 /* save the trust user dn */
1126 trusted_domain_state->trusted_domain_user_dn
1127 = talloc_steal(trusted_domain_state, user_dn);
1130 ret = ldb_transaction_commit(sam_ldb);
1131 if (ret != LDB_SUCCESS) {
1132 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1135 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1136 if (!handle) {
1137 return NT_STATUS_NO_MEMORY;
1140 handle->data = talloc_steal(handle, trusted_domain_state);
1142 trusted_domain_state->access_mask = r->in.access_mask;
1143 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1145 *r->out.trustdom_handle = handle->wire_handle;
1147 return NT_STATUS_OK;
1151 lsa_CreateTrustedDomainEx2
1153 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
1154 TALLOC_CTX *mem_ctx,
1155 struct lsa_CreateTrustedDomainEx2 *r)
1157 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, r, NDR_LSA_CREATETRUSTEDDOMAINEX2);
1160 lsa_CreateTrustedDomainEx
1162 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
1163 TALLOC_CTX *mem_ctx,
1164 struct lsa_CreateTrustedDomainEx *r)
1166 struct lsa_CreateTrustedDomainEx2 r2;
1168 r2.in.policy_handle = r->in.policy_handle;
1169 r2.in.info = r->in.info;
1170 r2.in.auth_info = r->in.auth_info;
1171 r2.out.trustdom_handle = r->out.trustdom_handle;
1172 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAINEX);
1176 lsa_CreateTrustedDomain
1178 static NTSTATUS dcesrv_lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1179 struct lsa_CreateTrustedDomain *r)
1181 struct lsa_CreateTrustedDomainEx2 r2;
1183 r2.in.policy_handle = r->in.policy_handle;
1184 r2.in.info = talloc(mem_ctx, struct lsa_TrustDomainInfoInfoEx);
1185 if (!r2.in.info) {
1186 return NT_STATUS_NO_MEMORY;
1189 r2.in.info->domain_name.string = NULL;
1190 r2.in.info->netbios_name = r->in.info->name;
1191 r2.in.info->sid = r->in.info->sid;
1192 r2.in.info->trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
1193 r2.in.info->trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1194 r2.in.info->trust_attributes = 0;
1196 r2.in.access_mask = r->in.access_mask;
1197 r2.out.trustdom_handle = r->out.trustdom_handle;
1199 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAIN);
1204 lsa_OpenTrustedDomain
1206 static NTSTATUS dcesrv_lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1207 struct lsa_OpenTrustedDomain *r)
1209 struct dcesrv_handle *policy_handle;
1211 struct lsa_policy_state *policy_state;
1212 struct lsa_trusted_domain_state *trusted_domain_state;
1213 struct dcesrv_handle *handle;
1214 struct ldb_message **msgs;
1215 const char *attrs[] = {
1216 "trustDirection",
1217 "flatname",
1218 NULL
1221 const char *sid_string;
1222 int ret;
1224 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1225 ZERO_STRUCTP(r->out.trustdom_handle);
1226 policy_state = policy_handle->data;
1228 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
1229 if (!trusted_domain_state) {
1230 return NT_STATUS_NO_MEMORY;
1232 trusted_domain_state->policy = policy_state;
1234 sid_string = dom_sid_string(mem_ctx, r->in.sid);
1235 if (!sid_string) {
1236 return NT_STATUS_NO_MEMORY;
1239 /* search for the trusted_domain record */
1240 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1241 mem_ctx, policy_state->system_dn, &msgs, attrs,
1242 "(&(securityIdentifier=%s)(objectclass=trustedDomain))",
1243 sid_string);
1244 if (ret == 0) {
1245 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1248 if (ret != 1) {
1249 DEBUG(0,("Found %d records matching DN %s\n", ret,
1250 ldb_dn_get_linearized(policy_state->system_dn)));
1251 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1254 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
1256 trusted_domain_state->trusted_domain_user_dn = NULL;
1258 if (ldb_msg_find_attr_as_int(msgs[0], "trustDirection", 0) & LSA_TRUST_DIRECTION_INBOUND) {
1259 const char *flatname = ldb_binary_encode_string(mem_ctx, ldb_msg_find_attr_as_string(msgs[0], "flatname", NULL));
1260 /* search for the trusted_domain record */
1261 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1262 mem_ctx, policy_state->domain_dn, &msgs, attrs,
1263 "(&(samaccountname=%s$)(objectclass=user)(userAccountControl:1.2.840.113556.1.4.803:=%d))",
1264 flatname, UF_INTERDOMAIN_TRUST_ACCOUNT);
1265 if (ret == 1) {
1266 trusted_domain_state->trusted_domain_user_dn = talloc_steal(trusted_domain_state, msgs[0]->dn);
1269 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1270 if (!handle) {
1271 return NT_STATUS_NO_MEMORY;
1274 handle->data = talloc_steal(handle, trusted_domain_state);
1276 trusted_domain_state->access_mask = r->in.access_mask;
1277 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1279 *r->out.trustdom_handle = handle->wire_handle;
1281 return NT_STATUS_OK;
1286 lsa_OpenTrustedDomainByName
1288 static NTSTATUS dcesrv_lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
1289 TALLOC_CTX *mem_ctx,
1290 struct lsa_OpenTrustedDomainByName *r)
1292 struct dcesrv_handle *policy_handle;
1294 struct lsa_policy_state *policy_state;
1295 struct lsa_trusted_domain_state *trusted_domain_state;
1296 struct dcesrv_handle *handle;
1297 struct ldb_message **msgs;
1298 const char *attrs[] = {
1299 NULL
1301 char *td_name;
1302 int ret;
1304 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1305 ZERO_STRUCTP(r->out.trustdom_handle);
1306 policy_state = policy_handle->data;
1308 if (!r->in.name.string) {
1309 return NT_STATUS_INVALID_PARAMETER;
1312 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
1313 if (!trusted_domain_state) {
1314 return NT_STATUS_NO_MEMORY;
1316 trusted_domain_state->policy = policy_state;
1318 /* search for the trusted_domain record */
1319 td_name = ldb_binary_encode_string(mem_ctx, r->in.name.string);
1320 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1321 mem_ctx, policy_state->system_dn, &msgs, attrs,
1322 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s))"
1323 "(objectclass=trustedDomain))",
1324 td_name, td_name, td_name);
1325 if (ret == 0) {
1326 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1329 if (ret != 1) {
1330 DEBUG(0,("Found %d records matching DN %s\n", ret,
1331 ldb_dn_get_linearized(policy_state->system_dn)));
1332 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1335 /* TODO: perform access checks */
1337 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
1339 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1340 if (!handle) {
1341 return NT_STATUS_NO_MEMORY;
1344 handle->data = talloc_steal(handle, trusted_domain_state);
1346 trusted_domain_state->access_mask = r->in.access_mask;
1347 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1349 *r->out.trustdom_handle = handle->wire_handle;
1351 return NT_STATUS_OK;
1357 lsa_SetTrustedDomainInfo
1359 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1360 struct lsa_SetTrustedDomainInfo *r)
1362 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1367 /* parameters 4 to 6 are optional if the dn is a dn of a TDO object,
1368 * otherwise at least one must be provided */
1369 static NTSTATUS get_tdo(struct ldb_context *sam, TALLOC_CTX *mem_ctx,
1370 struct ldb_dn *basedn, const char *dns_domain,
1371 const char *netbios, struct dom_sid2 *sid,
1372 struct ldb_message ***msgs)
1374 const char *attrs[] = { "flatname", "trustPartner",
1375 "securityIdentifier", "trustDirection",
1376 "trustType", "trustAttributes",
1377 "trustPosixOffset",
1378 "msDs-supportedEncryptionTypes", NULL };
1379 char *dns = NULL;
1380 char *nbn = NULL;
1381 char *sidstr = NULL;
1382 char *filter;
1383 int ret;
1386 if (dns_domain || netbios || sid) {
1387 filter = talloc_strdup(mem_ctx,
1388 "(&(objectclass=trustedDomain)(|");
1389 } else {
1390 filter = talloc_strdup(mem_ctx,
1391 "(objectclass=trustedDomain)");
1393 if (!filter) {
1394 return NT_STATUS_NO_MEMORY;
1397 if (dns_domain) {
1398 dns = ldb_binary_encode_string(mem_ctx, dns_domain);
1399 if (!dns) {
1400 return NT_STATUS_NO_MEMORY;
1402 filter = talloc_asprintf_append(filter,
1403 "(trustPartner=%s)", dns);
1404 if (!filter) {
1405 return NT_STATUS_NO_MEMORY;
1408 if (netbios) {
1409 nbn = ldb_binary_encode_string(mem_ctx, netbios);
1410 if (!nbn) {
1411 return NT_STATUS_NO_MEMORY;
1413 filter = talloc_asprintf_append(filter,
1414 "(flatname=%s)", nbn);
1415 if (!filter) {
1416 return NT_STATUS_NO_MEMORY;
1419 if (sid) {
1420 sidstr = dom_sid_string(mem_ctx, sid);
1421 if (!sidstr) {
1422 return NT_STATUS_INVALID_PARAMETER;
1424 filter = talloc_asprintf_append(filter,
1425 "(securityIdentifier=%s)",
1426 sidstr);
1427 if (!filter) {
1428 return NT_STATUS_NO_MEMORY;
1431 if (dns_domain || netbios || sid) {
1432 filter = talloc_asprintf_append(filter, "))");
1433 if (!filter) {
1434 return NT_STATUS_NO_MEMORY;
1438 ret = gendb_search(sam, mem_ctx, basedn, msgs, attrs, "%s", filter);
1439 if (ret == 0) {
1440 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1443 if (ret != 1) {
1444 return NT_STATUS_OBJECT_NAME_COLLISION;
1447 return NT_STATUS_OK;
1450 static NTSTATUS update_uint32_t_value(TALLOC_CTX *mem_ctx,
1451 struct ldb_message *orig,
1452 struct ldb_message *dest,
1453 const char *attribute,
1454 uint32_t value,
1455 uint32_t *orig_value)
1457 const struct ldb_val *orig_val;
1458 uint32_t orig_uint = 0;
1459 char *str_val;
1460 int flags = 0;
1461 int ret;
1463 orig_val = ldb_msg_find_ldb_val(orig, attribute);
1464 if (!orig_val || !orig_val->data) {
1465 /* add new attribute */
1466 flags = LDB_FLAG_MOD_ADD;
1468 } else {
1469 errno = 0;
1470 orig_uint = strtoul((const char *)orig_val->data, NULL, 0);
1471 if (errno != 0 || orig_uint != value) {
1472 /* replace also if can't get value */
1473 flags = LDB_FLAG_MOD_REPLACE;
1477 if (flags == 0) {
1478 /* stored value is identical, nothing to change */
1479 goto done;
1482 ret = ldb_msg_add_empty(dest, attribute, flags, NULL);
1483 if (ret != LDB_SUCCESS) {
1484 return NT_STATUS_NO_MEMORY;
1487 str_val = talloc_asprintf(mem_ctx, "%u", value);
1488 if (!str_val) {
1489 return NT_STATUS_NO_MEMORY;
1491 ret = ldb_msg_add_steal_string(dest, attribute, str_val);
1492 if (ret != LDB_SUCCESS) {
1493 return NT_STATUS_NO_MEMORY;
1496 done:
1497 if (orig_value) {
1498 *orig_value = orig_uint;
1500 return NT_STATUS_OK;
1503 static NTSTATUS update_trust_user(TALLOC_CTX *mem_ctx,
1504 struct ldb_context *sam_ldb,
1505 struct ldb_dn *base_dn,
1506 bool delete_user,
1507 const char *netbios_name,
1508 struct trustCurrentPasswords *in)
1510 const char *attrs[] = { "userAccountControl", NULL };
1511 struct ldb_message **msgs;
1512 struct ldb_message *msg;
1513 uint32_t uac;
1514 uint32_t i;
1515 int ret;
1517 ret = gendb_search(sam_ldb, mem_ctx,
1518 base_dn, &msgs, attrs,
1519 "samAccountName=%s$", netbios_name);
1520 if (ret > 1) {
1521 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1524 if (ret == 0) {
1525 if (delete_user) {
1526 return NT_STATUS_OK;
1529 /* ok no existing user, add it from scratch */
1530 return add_trust_user(mem_ctx, sam_ldb, base_dn,
1531 netbios_name, in, NULL);
1534 /* check user is what we are looking for */
1535 uac = ldb_msg_find_attr_as_uint(msgs[0],
1536 "userAccountControl", 0);
1537 if (!(uac & UF_INTERDOMAIN_TRUST_ACCOUNT)) {
1538 return NT_STATUS_OBJECT_NAME_COLLISION;
1541 if (delete_user) {
1542 ret = ldb_delete(sam_ldb, msgs[0]->dn);
1543 switch (ret) {
1544 case LDB_SUCCESS:
1545 return NT_STATUS_OK;
1546 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1547 return NT_STATUS_ACCESS_DENIED;
1548 default:
1549 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1553 /* entry exists, just modify secret if any */
1554 if (in->count == 0) {
1555 return NT_STATUS_OK;
1558 msg = ldb_msg_new(mem_ctx);
1559 if (!msg) {
1560 return NT_STATUS_NO_MEMORY;
1562 msg->dn = msgs[0]->dn;
1564 for (i = 0; i < in->count; i++) {
1565 const char *attribute;
1566 struct ldb_val v;
1567 switch (in->current[i]->AuthType) {
1568 case TRUST_AUTH_TYPE_NT4OWF:
1569 attribute = "unicodePwd";
1570 v.data = (uint8_t *)&in->current[i]->AuthInfo.nt4owf.password;
1571 v.length = 16;
1572 break;
1573 case TRUST_AUTH_TYPE_CLEAR:
1574 attribute = "clearTextPassword";
1575 v.data = in->current[i]->AuthInfo.clear.password;
1576 v.length = in->current[i]->AuthInfo.clear.size;
1577 break;
1578 default:
1579 continue;
1582 ret = ldb_msg_add_empty(msg, attribute,
1583 LDB_FLAG_MOD_REPLACE, NULL);
1584 if (ret != LDB_SUCCESS) {
1585 return NT_STATUS_NO_MEMORY;
1588 ret = ldb_msg_add_value(msg, attribute, &v, NULL);
1589 if (ret != LDB_SUCCESS) {
1590 return NT_STATUS_NO_MEMORY;
1594 /* create the trusted_domain user account */
1595 ret = ldb_modify(sam_ldb, msg);
1596 if (ret != LDB_SUCCESS) {
1597 DEBUG(0,("Failed to create user record %s: %s\n",
1598 ldb_dn_get_linearized(msg->dn),
1599 ldb_errstring(sam_ldb)));
1601 switch (ret) {
1602 case LDB_ERR_ENTRY_ALREADY_EXISTS:
1603 return NT_STATUS_DOMAIN_EXISTS;
1604 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1605 return NT_STATUS_ACCESS_DENIED;
1606 default:
1607 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1611 return NT_STATUS_OK;
1615 static NTSTATUS setInfoTrustedDomain_base(struct dcesrv_call_state *dce_call,
1616 struct dcesrv_handle *p_handle,
1617 TALLOC_CTX *mem_ctx,
1618 struct ldb_message *dom_msg,
1619 enum lsa_TrustDomInfoEnum level,
1620 union lsa_TrustedDomainInfo *info)
1622 struct lsa_policy_state *p_state = p_handle->data;
1623 uint32_t *posix_offset = NULL;
1624 struct lsa_TrustDomainInfoInfoEx *info_ex = NULL;
1625 struct lsa_TrustDomainInfoAuthInfo *auth_info = NULL;
1626 struct lsa_TrustDomainInfoAuthInfoInternal *auth_info_int = NULL;
1627 uint32_t *enc_types = NULL;
1628 DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob;
1629 struct trustDomainPasswords auth_struct;
1630 NTSTATUS nt_status;
1631 struct ldb_message **msgs;
1632 struct ldb_message *msg;
1633 bool add_outgoing = false;
1634 bool add_incoming = false;
1635 bool del_outgoing = false;
1636 bool del_incoming = false;
1637 bool in_transaction = false;
1638 int ret;
1640 switch (level) {
1641 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1642 posix_offset = &info->posix_offset.posix_offset;
1643 break;
1644 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1645 info_ex = &info->info_ex;
1646 break;
1647 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
1648 auth_info = &info->auth_info;
1649 break;
1650 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1651 posix_offset = &info->full_info.posix_offset.posix_offset;
1652 info_ex = &info->full_info.info_ex;
1653 auth_info = &info->full_info.auth_info;
1654 break;
1655 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
1656 auth_info_int = &info->auth_info_internal;
1657 break;
1658 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
1659 posix_offset = &info->full_info_internal.posix_offset.posix_offset;
1660 info_ex = &info->full_info_internal.info_ex;
1661 auth_info_int = &info->full_info_internal.auth_info;
1662 break;
1663 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
1664 enc_types = &info->enc_types.enc_types;
1665 break;
1666 default:
1667 return NT_STATUS_INVALID_PARAMETER;
1670 if (auth_info) {
1671 /* FIXME: not handled yet */
1672 return NT_STATUS_INVALID_PARAMETER;
1675 /* decode auth_info_int if set */
1676 if (auth_info_int) {
1678 /* now decrypt blob */
1679 auth_blob = data_blob_const(auth_info_int->auth_blob.data,
1680 auth_info_int->auth_blob.size);
1682 nt_status = get_trustdom_auth_blob(dce_call, mem_ctx,
1683 &auth_blob, &auth_struct);
1684 if (!NT_STATUS_IS_OK(nt_status)) {
1685 return nt_status;
1689 if (info_ex) {
1690 /* verify data matches */
1691 if (info_ex->trust_attributes &
1692 LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
1693 /* TODO: check what behavior level we have */
1694 if (strcasecmp_m(p_state->domain_dns,
1695 p_state->forest_dns) != 0) {
1696 return NT_STATUS_INVALID_DOMAIN_STATE;
1700 if (samdb_rodc(p_state->sam_ldb)) {
1701 return NT_STATUS_NO_SUCH_DOMAIN;
1704 /* verify only one object matches the dns/netbios/sid
1705 * triplet and that this is the one we already have */
1706 nt_status = get_tdo(p_state->sam_ldb, mem_ctx,
1707 p_state->system_dn,
1708 info_ex->domain_name.string,
1709 info_ex->netbios_name.string,
1710 info_ex->sid, &msgs);
1711 if (!NT_STATUS_IS_OK(nt_status)) {
1712 return nt_status;
1714 if (ldb_dn_compare(dom_msg->dn, msgs[0]->dn) != 0) {
1715 return NT_STATUS_OBJECT_NAME_COLLISION;
1717 talloc_free(msgs);
1720 /* TODO: should we fetch previous values from the existing entry
1721 * and append them ? */
1722 if (auth_struct.incoming.count) {
1723 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
1724 &auth_struct.incoming,
1725 &trustAuthIncoming);
1726 if (!NT_STATUS_IS_OK(nt_status)) {
1727 return nt_status;
1729 } else {
1730 trustAuthIncoming = data_blob(NULL, 0);
1733 if (auth_struct.outgoing.count) {
1734 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
1735 &auth_struct.outgoing,
1736 &trustAuthOutgoing);
1737 if (!NT_STATUS_IS_OK(nt_status)) {
1738 return nt_status;
1740 } else {
1741 trustAuthOutgoing = data_blob(NULL, 0);
1744 msg = ldb_msg_new(mem_ctx);
1745 if (msg == NULL) {
1746 return NT_STATUS_NO_MEMORY;
1748 msg->dn = dom_msg->dn;
1750 if (posix_offset) {
1751 nt_status = update_uint32_t_value(mem_ctx, dom_msg, msg,
1752 "trustPosixOffset",
1753 *posix_offset, NULL);
1754 if (!NT_STATUS_IS_OK(nt_status)) {
1755 return nt_status;
1759 if (info_ex) {
1760 uint32_t origattrs;
1761 uint32_t origdir;
1762 uint32_t tmp;
1763 int origtype;
1765 nt_status = update_uint32_t_value(mem_ctx, dom_msg, msg,
1766 "trustDirection",
1767 info_ex->trust_direction,
1768 &origdir);
1769 if (!NT_STATUS_IS_OK(nt_status)) {
1770 return nt_status;
1773 tmp = info_ex->trust_direction ^ origdir;
1774 if (tmp & LSA_TRUST_DIRECTION_INBOUND) {
1775 if (origdir & LSA_TRUST_DIRECTION_INBOUND) {
1776 del_incoming = true;
1777 } else {
1778 add_incoming = true;
1781 if (tmp & LSA_TRUST_DIRECTION_OUTBOUND) {
1782 if (origdir & LSA_TRUST_DIRECTION_OUTBOUND) {
1783 del_outgoing = true;
1784 } else {
1785 add_outgoing = true;
1789 origtype = ldb_msg_find_attr_as_int(dom_msg, "trustType", -1);
1790 if (origtype == -1 || origtype != info_ex->trust_type) {
1791 DEBUG(1, ("Attempted to change trust type! "
1792 "Operation not handled\n"));
1793 return NT_STATUS_INVALID_PARAMETER;
1796 nt_status = update_uint32_t_value(mem_ctx, dom_msg, msg,
1797 "trustAttributes",
1798 info_ex->trust_attributes,
1799 &origattrs);
1800 if (!NT_STATUS_IS_OK(nt_status)) {
1801 return nt_status;
1803 /* TODO: check forestFunctionality from ldb opaque */
1804 /* TODO: check what is set makes sense */
1805 /* for now refuse changes */
1806 if (origattrs == -1 ||
1807 origattrs != info_ex->trust_attributes) {
1808 DEBUG(1, ("Attempted to change trust attributes! "
1809 "Operation not handled\n"));
1810 return NT_STATUS_INVALID_PARAMETER;
1814 if (enc_types) {
1815 nt_status = update_uint32_t_value(mem_ctx, dom_msg, msg,
1816 "msDS-SupportedEncryptionTypes",
1817 *enc_types, NULL);
1818 if (!NT_STATUS_IS_OK(nt_status)) {
1819 return nt_status;
1823 if (add_incoming && trustAuthIncoming.data) {
1824 ret = ldb_msg_add_empty(msg, "trustAuthIncoming",
1825 LDB_FLAG_MOD_REPLACE, NULL);
1826 if (ret != LDB_SUCCESS) {
1827 return NT_STATUS_NO_MEMORY;
1829 ret = ldb_msg_add_value(msg, "trustAuthIncoming",
1830 &trustAuthIncoming, NULL);
1831 if (ret != LDB_SUCCESS) {
1832 return NT_STATUS_NO_MEMORY;
1835 if (add_outgoing && trustAuthOutgoing.data) {
1836 ret = ldb_msg_add_empty(msg, "trustAuthIncoming",
1837 LDB_FLAG_MOD_REPLACE, NULL);
1838 if (ret != LDB_SUCCESS) {
1839 return NT_STATUS_NO_MEMORY;
1841 ret = ldb_msg_add_value(msg, "trustAuthOutgoing",
1842 &trustAuthOutgoing, NULL);
1843 if (ret != LDB_SUCCESS) {
1844 return NT_STATUS_NO_MEMORY;
1848 /* start transaction */
1849 ret = ldb_transaction_start(p_state->sam_ldb);
1850 if (ret != LDB_SUCCESS) {
1851 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1853 in_transaction = true;
1855 ret = ldb_modify(p_state->sam_ldb, msg);
1856 if (ret != LDB_SUCCESS) {
1857 DEBUG(1,("Failed to modify trusted domain record %s: %s\n",
1858 ldb_dn_get_linearized(msg->dn),
1859 ldb_errstring(p_state->sam_ldb)));
1860 if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) {
1861 nt_status = NT_STATUS_ACCESS_DENIED;
1862 } else {
1863 nt_status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1865 goto done;
1868 if (add_incoming || del_incoming) {
1869 const char *netbios_name;
1871 netbios_name = ldb_msg_find_attr_as_string(dom_msg,
1872 "flatname", NULL);
1873 if (!netbios_name) {
1874 nt_status = NT_STATUS_INVALID_DOMAIN_STATE;
1875 goto done;
1878 nt_status = update_trust_user(mem_ctx,
1879 p_state->sam_ldb,
1880 p_state->domain_dn,
1881 del_incoming,
1882 netbios_name,
1883 &auth_struct.incoming);
1884 if (!NT_STATUS_IS_OK(nt_status)) {
1885 goto done;
1889 /* ok, all fine, commit transaction and return */
1890 ret = ldb_transaction_commit(p_state->sam_ldb);
1891 if (ret != LDB_SUCCESS) {
1892 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1894 in_transaction = false;
1896 nt_status = NT_STATUS_OK;
1898 done:
1899 if (in_transaction) {
1900 ldb_transaction_cancel(p_state->sam_ldb);
1902 return nt_status;
1906 lsa_SetInfomrationTrustedDomain
1908 static NTSTATUS dcesrv_lsa_SetInformationTrustedDomain(
1909 struct dcesrv_call_state *dce_call,
1910 TALLOC_CTX *mem_ctx,
1911 struct lsa_SetInformationTrustedDomain *r)
1913 struct dcesrv_handle *h;
1914 struct lsa_trusted_domain_state *td_state;
1915 struct ldb_message **msgs;
1916 NTSTATUS nt_status;
1918 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle,
1919 LSA_HANDLE_TRUSTED_DOMAIN);
1921 td_state = talloc_get_type(h->data, struct lsa_trusted_domain_state);
1923 /* get the trusted domain object */
1924 nt_status = get_tdo(td_state->policy->sam_ldb, mem_ctx,
1925 td_state->trusted_domain_dn,
1926 NULL, NULL, NULL, &msgs);
1927 if (!NT_STATUS_IS_OK(nt_status)) {
1928 if (NT_STATUS_EQUAL(nt_status,
1929 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1930 return nt_status;
1932 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1935 return setInfoTrustedDomain_base(dce_call, h, mem_ctx,
1936 msgs[0], r->in.level, r->in.info);
1941 lsa_DeleteTrustedDomain
1943 static NTSTATUS dcesrv_lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1944 struct lsa_DeleteTrustedDomain *r)
1946 NTSTATUS status;
1947 struct lsa_OpenTrustedDomain opn;
1948 struct lsa_DeleteObject del;
1949 struct dcesrv_handle *h;
1951 opn.in.handle = r->in.handle;
1952 opn.in.sid = r->in.dom_sid;
1953 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1954 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1955 if (!opn.out.trustdom_handle) {
1956 return NT_STATUS_NO_MEMORY;
1958 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
1959 if (!NT_STATUS_IS_OK(status)) {
1960 return status;
1963 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
1964 talloc_steal(mem_ctx, h);
1966 del.in.handle = opn.out.trustdom_handle;
1967 del.out.handle = opn.out.trustdom_handle;
1968 status = dcesrv_lsa_DeleteObject(dce_call, mem_ctx, &del);
1969 if (!NT_STATUS_IS_OK(status)) {
1970 return status;
1972 return NT_STATUS_OK;
1975 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx,
1976 struct ldb_message *msg,
1977 struct lsa_TrustDomainInfoInfoEx *info_ex)
1979 info_ex->domain_name.string
1980 = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
1981 info_ex->netbios_name.string
1982 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1983 info_ex->sid
1984 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1985 info_ex->trust_direction
1986 = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
1987 info_ex->trust_type
1988 = ldb_msg_find_attr_as_int(msg, "trustType", 0);
1989 info_ex->trust_attributes
1990 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);
1991 return NT_STATUS_OK;
1995 lsa_QueryTrustedDomainInfo
1997 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1998 struct lsa_QueryTrustedDomainInfo *r)
2000 union lsa_TrustedDomainInfo *info = NULL;
2001 struct dcesrv_handle *h;
2002 struct lsa_trusted_domain_state *trusted_domain_state;
2003 struct ldb_message *msg;
2004 int ret;
2005 struct ldb_message **res;
2006 const char *attrs[] = {
2007 "flatname",
2008 "trustPartner",
2009 "securityIdentifier",
2010 "trustDirection",
2011 "trustType",
2012 "trustAttributes",
2013 "msDs-supportedEncryptionTypes",
2014 NULL
2017 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
2019 trusted_domain_state = talloc_get_type(h->data, struct lsa_trusted_domain_state);
2021 /* pull all the user attributes */
2022 ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
2023 trusted_domain_state->trusted_domain_dn, &res, attrs);
2024 if (ret != 1) {
2025 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2027 msg = res[0];
2029 info = talloc_zero(mem_ctx, union lsa_TrustedDomainInfo);
2030 if (!info) {
2031 return NT_STATUS_NO_MEMORY;
2033 *r->out.info = info;
2035 switch (r->in.level) {
2036 case LSA_TRUSTED_DOMAIN_INFO_NAME:
2037 info->name.netbios_name.string
2038 = samdb_result_string(msg, "flatname", NULL);
2039 break;
2040 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2041 info->posix_offset.posix_offset
2042 = samdb_result_uint(msg, "posixOffset", 0);
2043 break;
2044 #if 0 /* Win2k3 doesn't implement this */
2045 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2046 r->out.info->info_basic.netbios_name.string
2047 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
2048 r->out.info->info_basic.sid
2049 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
2050 break;
2051 #endif
2052 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2053 return fill_trust_domain_ex(mem_ctx, msg, &info->info_ex);
2055 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2056 ZERO_STRUCT(info->full_info);
2057 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info.info_ex);
2059 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2060 ZERO_STRUCT(info->full_info2_internal);
2061 info->full_info2_internal.posix_offset.posix_offset
2062 = samdb_result_uint(msg, "posixOffset", 0);
2063 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info2_internal.info.info_ex);
2065 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2066 info->enc_types.enc_types
2067 = samdb_result_uint(msg, "msDs-supportedEncryptionTypes", KERB_ENCTYPE_RC4_HMAC_MD5);
2068 break;
2070 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2071 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2072 /* oops, we don't want to return the info after all */
2073 talloc_free(info);
2074 *r->out.info = NULL;
2075 return NT_STATUS_INVALID_PARAMETER;
2076 default:
2077 /* oops, we don't want to return the info after all */
2078 talloc_free(info);
2079 *r->out.info = NULL;
2080 return NT_STATUS_INVALID_INFO_CLASS;
2083 return NT_STATUS_OK;
2088 lsa_QueryTrustedDomainInfoBySid
2090 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2091 struct lsa_QueryTrustedDomainInfoBySid *r)
2093 NTSTATUS status;
2094 struct lsa_OpenTrustedDomain opn;
2095 struct lsa_QueryTrustedDomainInfo query;
2096 struct dcesrv_handle *h;
2098 opn.in.handle = r->in.handle;
2099 opn.in.sid = r->in.dom_sid;
2100 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2101 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
2102 if (!opn.out.trustdom_handle) {
2103 return NT_STATUS_NO_MEMORY;
2105 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
2106 if (!NT_STATUS_IS_OK(status)) {
2107 return status;
2110 /* Ensure this handle goes away at the end of this call */
2111 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
2112 talloc_steal(mem_ctx, h);
2114 query.in.trustdom_handle = opn.out.trustdom_handle;
2115 query.in.level = r->in.level;
2116 query.out.info = r->out.info;
2117 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
2118 if (!NT_STATUS_IS_OK(status)) {
2119 return status;
2122 return NT_STATUS_OK;
2126 lsa_SetTrustedDomainInfoByName
2128 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
2129 TALLOC_CTX *mem_ctx,
2130 struct lsa_SetTrustedDomainInfoByName *r)
2132 struct dcesrv_handle *policy_handle;
2133 struct lsa_policy_state *policy_state;
2134 struct ldb_message **msgs;
2135 NTSTATUS nt_status;
2137 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2138 policy_state = policy_handle->data;
2140 /* get the trusted domain object */
2141 nt_status = get_tdo(policy_state->sam_ldb, mem_ctx,
2142 policy_state->domain_dn,
2143 r->in.trusted_domain->string,
2144 r->in.trusted_domain->string,
2145 NULL, &msgs);
2146 if (!NT_STATUS_IS_OK(nt_status)) {
2147 if (NT_STATUS_EQUAL(nt_status,
2148 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2149 return nt_status;
2151 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2154 return setInfoTrustedDomain_base(dce_call, policy_handle, mem_ctx,
2155 msgs[0], r->in.level, r->in.info);
2159 lsa_QueryTrustedDomainInfoByName
2161 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
2162 TALLOC_CTX *mem_ctx,
2163 struct lsa_QueryTrustedDomainInfoByName *r)
2165 NTSTATUS status;
2166 struct lsa_OpenTrustedDomainByName opn;
2167 struct lsa_QueryTrustedDomainInfo query;
2168 struct dcesrv_handle *h;
2170 opn.in.handle = r->in.handle;
2171 opn.in.name = *r->in.trusted_domain;
2172 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2173 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
2174 if (!opn.out.trustdom_handle) {
2175 return NT_STATUS_NO_MEMORY;
2177 status = dcesrv_lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &opn);
2178 if (!NT_STATUS_IS_OK(status)) {
2179 return status;
2182 /* Ensure this handle goes away at the end of this call */
2183 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
2184 talloc_steal(mem_ctx, h);
2186 query.in.trustdom_handle = opn.out.trustdom_handle;
2187 query.in.level = r->in.level;
2188 query.out.info = r->out.info;
2189 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
2190 if (!NT_STATUS_IS_OK(status)) {
2191 return status;
2194 return NT_STATUS_OK;
2198 lsa_CloseTrustedDomainEx
2200 static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
2201 TALLOC_CTX *mem_ctx,
2202 struct lsa_CloseTrustedDomainEx *r)
2204 /* The result of a bad hair day from an IDL programmer? Not
2205 * implmented in Win2k3. You should always just lsa_Close
2206 * anyway. */
2207 return NT_STATUS_NOT_IMPLEMENTED;
2212 comparison function for sorting lsa_DomainInformation array
2214 static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
2216 return strcasecmp_m(e1->name.string, e2->name.string);
2220 lsa_EnumTrustDom
2222 static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2223 struct lsa_EnumTrustDom *r)
2225 struct dcesrv_handle *policy_handle;
2226 struct lsa_DomainInfo *entries;
2227 struct lsa_policy_state *policy_state;
2228 struct ldb_message **domains;
2229 const char *attrs[] = {
2230 "flatname",
2231 "securityIdentifier",
2232 NULL
2236 int count, i;
2238 *r->out.resume_handle = 0;
2240 r->out.domains->domains = NULL;
2241 r->out.domains->count = 0;
2243 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2245 policy_state = policy_handle->data;
2247 /* search for all users in this domain. This could possibly be cached and
2248 resumed based on resume_key */
2249 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
2250 "objectclass=trustedDomain");
2251 if (count < 0) {
2252 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2255 /* convert to lsa_TrustInformation format */
2256 entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
2257 if (!entries) {
2258 return NT_STATUS_NO_MEMORY;
2260 for (i=0;i<count;i++) {
2261 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
2262 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
2265 /* sort the results by name */
2266 TYPESAFE_QSORT(entries, count, compare_DomainInfo);
2268 if (*r->in.resume_handle >= count) {
2269 *r->out.resume_handle = -1;
2271 return NT_STATUS_NO_MORE_ENTRIES;
2274 /* return the rest, limit by max_size. Note that we
2275 use the w2k3 element size value of 60 */
2276 r->out.domains->count = count - *r->in.resume_handle;
2277 r->out.domains->count = MIN(r->out.domains->count,
2278 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
2280 r->out.domains->domains = entries + *r->in.resume_handle;
2281 r->out.domains->count = r->out.domains->count;
2283 if (r->out.domains->count < count - *r->in.resume_handle) {
2284 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
2285 return STATUS_MORE_ENTRIES;
2288 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
2289 * always be larger than the previous input resume handle, in
2290 * particular when hitting the last query it is vital to set the
2291 * resume handle correctly to avoid infinite client loops, as
2292 * seen e.g. with Windows XP SP3 when resume handle is 0 and
2293 * status is NT_STATUS_OK - gd */
2295 *r->out.resume_handle = (uint32_t)-1;
2297 return NT_STATUS_OK;
2301 comparison function for sorting lsa_DomainInformation array
2303 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
2305 return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
2309 lsa_EnumTrustedDomainsEx
2311 static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2312 struct lsa_EnumTrustedDomainsEx *r)
2314 struct dcesrv_handle *policy_handle;
2315 struct lsa_TrustDomainInfoInfoEx *entries;
2316 struct lsa_policy_state *policy_state;
2317 struct ldb_message **domains;
2318 const char *attrs[] = {
2319 "flatname",
2320 "trustPartner",
2321 "securityIdentifier",
2322 "trustDirection",
2323 "trustType",
2324 "trustAttributes",
2325 NULL
2327 NTSTATUS nt_status;
2329 int count, i;
2331 *r->out.resume_handle = 0;
2333 r->out.domains->domains = NULL;
2334 r->out.domains->count = 0;
2336 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2338 policy_state = policy_handle->data;
2340 /* search for all users in this domain. This could possibly be cached and
2341 resumed based on resume_key */
2342 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
2343 "objectclass=trustedDomain");
2344 if (count < 0) {
2345 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2348 /* convert to lsa_DomainInformation format */
2349 entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
2350 if (!entries) {
2351 return NT_STATUS_NO_MEMORY;
2353 for (i=0;i<count;i++) {
2354 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
2355 if (!NT_STATUS_IS_OK(nt_status)) {
2356 return nt_status;
2360 /* sort the results by name */
2361 TYPESAFE_QSORT(entries, count, compare_TrustDomainInfoInfoEx);
2363 if (*r->in.resume_handle >= count) {
2364 *r->out.resume_handle = -1;
2366 return NT_STATUS_NO_MORE_ENTRIES;
2369 /* return the rest, limit by max_size. Note that we
2370 use the w2k3 element size value of 60 */
2371 r->out.domains->count = count - *r->in.resume_handle;
2372 r->out.domains->count = MIN(r->out.domains->count,
2373 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
2375 r->out.domains->domains = entries + *r->in.resume_handle;
2376 r->out.domains->count = r->out.domains->count;
2378 if (r->out.domains->count < count - *r->in.resume_handle) {
2379 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
2380 return STATUS_MORE_ENTRIES;
2383 return NT_STATUS_OK;
2388 lsa_OpenAccount
2390 static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2391 struct lsa_OpenAccount *r)
2393 struct dcesrv_handle *h, *ah;
2394 struct lsa_policy_state *state;
2395 struct lsa_account_state *astate;
2397 ZERO_STRUCTP(r->out.acct_handle);
2399 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2401 state = h->data;
2403 astate = talloc(dce_call->conn, struct lsa_account_state);
2404 if (astate == NULL) {
2405 return NT_STATUS_NO_MEMORY;
2408 astate->account_sid = dom_sid_dup(astate, r->in.sid);
2409 if (astate->account_sid == NULL) {
2410 talloc_free(astate);
2411 return NT_STATUS_NO_MEMORY;
2414 astate->policy = talloc_reference(astate, state);
2415 astate->access_mask = r->in.access_mask;
2417 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
2418 if (!ah) {
2419 talloc_free(astate);
2420 return NT_STATUS_NO_MEMORY;
2423 ah->data = talloc_steal(ah, astate);
2425 *r->out.acct_handle = ah->wire_handle;
2427 return NT_STATUS_OK;
2432 lsa_EnumPrivsAccount
2434 static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
2435 TALLOC_CTX *mem_ctx,
2436 struct lsa_EnumPrivsAccount *r)
2438 struct dcesrv_handle *h;
2439 struct lsa_account_state *astate;
2440 int ret;
2441 unsigned int i;
2442 struct ldb_message **res;
2443 const char * const attrs[] = { "privilege", NULL};
2444 struct ldb_message_element *el;
2445 const char *sidstr;
2446 struct lsa_PrivilegeSet *privs;
2448 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2450 astate = h->data;
2452 privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
2453 if (privs == NULL) {
2454 return NT_STATUS_NO_MEMORY;
2456 privs->count = 0;
2457 privs->unknown = 0;
2458 privs->set = NULL;
2460 *r->out.privs = privs;
2462 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
2463 if (sidstr == NULL) {
2464 return NT_STATUS_NO_MEMORY;
2467 ret = gendb_search(astate->policy->pdb, mem_ctx, NULL, &res, attrs,
2468 "objectSid=%s", sidstr);
2469 if (ret < 0) {
2470 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2472 if (ret != 1) {
2473 return NT_STATUS_OK;
2476 el = ldb_msg_find_element(res[0], "privilege");
2477 if (el == NULL || el->num_values == 0) {
2478 return NT_STATUS_OK;
2481 privs->set = talloc_array(privs,
2482 struct lsa_LUIDAttribute, el->num_values);
2483 if (privs->set == NULL) {
2484 return NT_STATUS_NO_MEMORY;
2487 for (i=0;i<el->num_values;i++) {
2488 int id = sec_privilege_id((const char *)el->values[i].data);
2489 if (id == -1) {
2490 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2492 privs->set[i].attribute = 0;
2493 privs->set[i].luid.low = id;
2494 privs->set[i].luid.high = 0;
2497 privs->count = el->num_values;
2499 return NT_STATUS_OK;
2503 lsa_EnumAccountRights
2505 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
2506 TALLOC_CTX *mem_ctx,
2507 struct lsa_EnumAccountRights *r)
2509 struct dcesrv_handle *h;
2510 struct lsa_policy_state *state;
2511 int ret;
2512 unsigned int i;
2513 struct ldb_message **res;
2514 const char * const attrs[] = { "privilege", NULL};
2515 const char *sidstr;
2516 struct ldb_message_element *el;
2518 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2520 state = h->data;
2522 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
2523 if (sidstr == NULL) {
2524 return NT_STATUS_NO_MEMORY;
2527 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
2528 "(&(objectSid=%s)(privilege=*))", sidstr);
2529 if (ret == 0) {
2530 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2532 if (ret != 1) {
2533 DEBUG(3, ("searching for account rights for SID: %s failed: %s",
2534 dom_sid_string(mem_ctx, r->in.sid),
2535 ldb_errstring(state->pdb)));
2536 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2539 el = ldb_msg_find_element(res[0], "privilege");
2540 if (el == NULL || el->num_values == 0) {
2541 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2544 r->out.rights->count = el->num_values;
2545 r->out.rights->names = talloc_array(r->out.rights,
2546 struct lsa_StringLarge, r->out.rights->count);
2547 if (r->out.rights->names == NULL) {
2548 return NT_STATUS_NO_MEMORY;
2551 for (i=0;i<el->num_values;i++) {
2552 r->out.rights->names[i].string = (const char *)el->values[i].data;
2555 return NT_STATUS_OK;
2561 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
2563 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
2564 TALLOC_CTX *mem_ctx,
2565 struct lsa_policy_state *state,
2566 int ldb_flag,
2567 struct dom_sid *sid,
2568 const struct lsa_RightSet *rights)
2570 const char *sidstr, *sidndrstr;
2571 struct ldb_message *msg;
2572 struct ldb_message_element *el;
2573 int ret;
2574 uint32_t i;
2575 struct lsa_EnumAccountRights r2;
2576 char *dnstr;
2578 if (security_session_user_level(dce_call->conn->auth_state.session_info) <
2579 SECURITY_ADMINISTRATOR) {
2580 DEBUG(0,("lsa_AddRemoveAccount refused for supplied security token\n"));
2581 return NT_STATUS_ACCESS_DENIED;
2584 msg = ldb_msg_new(mem_ctx);
2585 if (msg == NULL) {
2586 return NT_STATUS_NO_MEMORY;
2589 sidndrstr = ldap_encode_ndr_dom_sid(msg, sid);
2590 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidndrstr, msg);
2592 sidstr = dom_sid_string(msg, sid);
2593 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidstr, msg);
2595 dnstr = talloc_asprintf(msg, "sid=%s", sidstr);
2596 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(dnstr, msg);
2598 msg->dn = ldb_dn_new(msg, state->pdb, dnstr);
2599 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg->dn, msg);
2601 if (ldb_flag == LDB_FLAG_MOD_ADD) {
2602 NTSTATUS status;
2604 r2.in.handle = &state->handle->wire_handle;
2605 r2.in.sid = sid;
2606 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
2608 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
2609 if (!NT_STATUS_IS_OK(status)) {
2610 ZERO_STRUCTP(r2.out.rights);
2614 for (i=0;i<rights->count;i++) {
2615 if (sec_privilege_id(rights->names[i].string) == -1) {
2616 talloc_free(msg);
2617 return NT_STATUS_NO_SUCH_PRIVILEGE;
2620 if (ldb_flag == LDB_FLAG_MOD_ADD) {
2621 uint32_t j;
2622 for (j=0;j<r2.out.rights->count;j++) {
2623 if (strcasecmp_m(r2.out.rights->names[j].string,
2624 rights->names[i].string) == 0) {
2625 break;
2628 if (j != r2.out.rights->count) continue;
2631 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
2632 if (ret != LDB_SUCCESS) {
2633 talloc_free(msg);
2634 return NT_STATUS_NO_MEMORY;
2638 el = ldb_msg_find_element(msg, "privilege");
2639 if (!el) {
2640 talloc_free(msg);
2641 return NT_STATUS_OK;
2644 el->flags = ldb_flag;
2646 ret = ldb_modify(state->pdb, msg);
2647 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
2648 if (samdb_msg_add_dom_sid(state->pdb, msg, msg, "objectSid", sid) != LDB_SUCCESS) {
2649 talloc_free(msg);
2650 return NT_STATUS_NO_MEMORY;
2652 samdb_msg_add_string(state->pdb, msg, msg, "comment", "added via LSA");
2653 ret = ldb_add(state->pdb, msg);
2655 if (ret != LDB_SUCCESS) {
2656 if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
2657 talloc_free(msg);
2658 return NT_STATUS_OK;
2660 DEBUG(3, ("Could not %s attributes from %s: %s",
2661 ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add",
2662 ldb_dn_get_linearized(msg->dn), ldb_errstring(state->pdb)));
2663 talloc_free(msg);
2664 return NT_STATUS_UNEXPECTED_IO_ERROR;
2667 talloc_free(msg);
2668 return NT_STATUS_OK;
2672 lsa_AddPrivilegesToAccount
2674 static NTSTATUS dcesrv_lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2675 struct lsa_AddPrivilegesToAccount *r)
2677 struct lsa_RightSet rights;
2678 struct dcesrv_handle *h;
2679 struct lsa_account_state *astate;
2680 uint32_t i;
2682 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2684 astate = h->data;
2686 rights.count = r->in.privs->count;
2687 rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
2688 if (rights.names == NULL) {
2689 return NT_STATUS_NO_MEMORY;
2691 for (i=0;i<rights.count;i++) {
2692 int id = r->in.privs->set[i].luid.low;
2693 if (r->in.privs->set[i].luid.high) {
2694 return NT_STATUS_NO_SUCH_PRIVILEGE;
2696 rights.names[i].string = sec_privilege_name(id);
2697 if (rights.names[i].string == NULL) {
2698 return NT_STATUS_NO_SUCH_PRIVILEGE;
2702 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2703 LDB_FLAG_MOD_ADD, astate->account_sid,
2704 &rights);
2709 lsa_RemovePrivilegesFromAccount
2711 static NTSTATUS dcesrv_lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2712 struct lsa_RemovePrivilegesFromAccount *r)
2714 struct lsa_RightSet *rights;
2715 struct dcesrv_handle *h;
2716 struct lsa_account_state *astate;
2717 uint32_t i;
2719 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2721 astate = h->data;
2723 rights = talloc(mem_ctx, struct lsa_RightSet);
2725 if (r->in.remove_all == 1 &&
2726 r->in.privs == NULL) {
2727 struct lsa_EnumAccountRights r2;
2728 NTSTATUS status;
2730 r2.in.handle = &astate->policy->handle->wire_handle;
2731 r2.in.sid = astate->account_sid;
2732 r2.out.rights = rights;
2734 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
2735 if (!NT_STATUS_IS_OK(status)) {
2736 return status;
2739 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2740 LDB_FLAG_MOD_DELETE, astate->account_sid,
2741 r2.out.rights);
2744 if (r->in.remove_all != 0) {
2745 return NT_STATUS_INVALID_PARAMETER;
2748 rights->count = r->in.privs->count;
2749 rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
2750 if (rights->names == NULL) {
2751 return NT_STATUS_NO_MEMORY;
2753 for (i=0;i<rights->count;i++) {
2754 int id = r->in.privs->set[i].luid.low;
2755 if (r->in.privs->set[i].luid.high) {
2756 return NT_STATUS_NO_SUCH_PRIVILEGE;
2758 rights->names[i].string = sec_privilege_name(id);
2759 if (rights->names[i].string == NULL) {
2760 return NT_STATUS_NO_SUCH_PRIVILEGE;
2764 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2765 LDB_FLAG_MOD_DELETE, astate->account_sid,
2766 rights);
2771 lsa_GetQuotasForAccount
2773 static NTSTATUS dcesrv_lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2774 struct lsa_GetQuotasForAccount *r)
2776 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2781 lsa_SetQuotasForAccount
2783 static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2784 struct lsa_SetQuotasForAccount *r)
2786 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2791 lsa_GetSystemAccessAccount
2793 static NTSTATUS dcesrv_lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2794 struct lsa_GetSystemAccessAccount *r)
2796 uint32_t i;
2797 NTSTATUS status;
2798 struct lsa_EnumPrivsAccount enumPrivs;
2799 struct lsa_PrivilegeSet *privs;
2801 privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
2802 if (!privs) {
2803 return NT_STATUS_NO_MEMORY;
2805 privs->count = 0;
2806 privs->unknown = 0;
2807 privs->set = NULL;
2809 enumPrivs.in.handle = r->in.handle;
2810 enumPrivs.out.privs = &privs;
2812 status = dcesrv_lsa_EnumPrivsAccount(dce_call, mem_ctx, &enumPrivs);
2813 if (!NT_STATUS_IS_OK(status)) {
2814 return status;
2817 *(r->out.access_mask) = 0x00000000;
2819 for (i = 0; i < privs->count; i++) {
2820 int priv = privs->set[i].luid.low;
2822 switch (priv) {
2823 case SEC_PRIV_INTERACTIVE_LOGON:
2824 *(r->out.access_mask) |= LSA_POLICY_MODE_INTERACTIVE;
2825 break;
2826 case SEC_PRIV_NETWORK_LOGON:
2827 *(r->out.access_mask) |= LSA_POLICY_MODE_NETWORK;
2828 break;
2829 case SEC_PRIV_REMOTE_INTERACTIVE_LOGON:
2830 *(r->out.access_mask) |= LSA_POLICY_MODE_REMOTE_INTERACTIVE;
2831 break;
2835 return NT_STATUS_OK;
2840 lsa_SetSystemAccessAccount
2842 static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2843 struct lsa_SetSystemAccessAccount *r)
2845 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2850 lsa_CreateSecret
2852 static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2853 struct lsa_CreateSecret *r)
2855 struct dcesrv_handle *policy_handle;
2856 struct lsa_policy_state *policy_state;
2857 struct lsa_secret_state *secret_state;
2858 struct dcesrv_handle *handle;
2859 struct ldb_message **msgs, *msg;
2860 const char *attrs[] = {
2861 NULL
2864 const char *name;
2866 int ret;
2868 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2869 ZERO_STRUCTP(r->out.sec_handle);
2871 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2873 case SECURITY_SYSTEM:
2874 case SECURITY_ADMINISTRATOR:
2875 break;
2876 default:
2877 /* Users and annonymous are not allowed create secrets */
2878 return NT_STATUS_ACCESS_DENIED;
2881 policy_state = policy_handle->data;
2883 if (!r->in.name.string) {
2884 return NT_STATUS_INVALID_PARAMETER;
2887 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2888 if (!secret_state) {
2889 return NT_STATUS_NO_MEMORY;
2891 secret_state->policy = policy_state;
2893 msg = ldb_msg_new(mem_ctx);
2894 if (msg == NULL) {
2895 return NT_STATUS_NO_MEMORY;
2898 if (strncmp("G$", r->in.name.string, 2) == 0) {
2899 const char *name2;
2900 name = &r->in.name.string[2];
2901 /* 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) */
2902 secret_state->sam_ldb = talloc_reference(secret_state,
2903 samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(dce_call->conn->dce_ctx->lp_ctx)));
2904 secret_state->global = true;
2906 if (strlen(name) < 1) {
2907 return NT_STATUS_INVALID_PARAMETER;
2910 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
2911 /* search for the secret record */
2912 ret = gendb_search(secret_state->sam_ldb,
2913 mem_ctx, policy_state->system_dn, &msgs, attrs,
2914 "(&(cn=%s)(objectclass=secret))",
2915 name2);
2916 if (ret > 0) {
2917 return NT_STATUS_OBJECT_NAME_COLLISION;
2920 if (ret < 0) {
2921 DEBUG(0,("Failure searching for CN=%s: %s\n",
2922 name2, ldb_errstring(secret_state->sam_ldb)));
2923 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2926 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
2927 if (!name2 || ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
2928 return NT_STATUS_NO_MEMORY;
2931 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
2933 } else {
2934 secret_state->global = false;
2936 name = r->in.name.string;
2937 if (strlen(name) < 1) {
2938 return NT_STATUS_INVALID_PARAMETER;
2941 secret_state->sam_ldb = talloc_reference(secret_state,
2942 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
2943 /* search for the secret record */
2944 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2945 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2946 &msgs, attrs,
2947 "(&(cn=%s)(objectclass=secret))",
2948 ldb_binary_encode_string(mem_ctx, name));
2949 if (ret > 0) {
2950 return NT_STATUS_OBJECT_NAME_COLLISION;
2953 if (ret < 0) {
2954 DEBUG(0,("Failure searching for CN=%s: %s\n",
2955 name, ldb_errstring(secret_state->sam_ldb)));
2956 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2959 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name);
2960 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
2963 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
2965 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
2967 /* create the secret */
2968 ret = ldb_add(secret_state->sam_ldb, msg);
2969 if (ret != LDB_SUCCESS) {
2970 DEBUG(0,("Failed to create secret record %s: %s\n",
2971 ldb_dn_get_linearized(msg->dn),
2972 ldb_errstring(secret_state->sam_ldb)));
2973 return NT_STATUS_ACCESS_DENIED;
2976 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2977 if (!handle) {
2978 return NT_STATUS_NO_MEMORY;
2981 handle->data = talloc_steal(handle, secret_state);
2983 secret_state->access_mask = r->in.access_mask;
2984 secret_state->policy = talloc_reference(secret_state, policy_state);
2986 *r->out.sec_handle = handle->wire_handle;
2988 return NT_STATUS_OK;
2993 lsa_OpenSecret
2995 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2996 struct lsa_OpenSecret *r)
2998 struct dcesrv_handle *policy_handle;
3000 struct lsa_policy_state *policy_state;
3001 struct lsa_secret_state *secret_state;
3002 struct dcesrv_handle *handle;
3003 struct ldb_message **msgs;
3004 const char *attrs[] = {
3005 NULL
3008 const char *name;
3010 int ret;
3012 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
3013 ZERO_STRUCTP(r->out.sec_handle);
3014 policy_state = policy_handle->data;
3016 if (!r->in.name.string) {
3017 return NT_STATUS_INVALID_PARAMETER;
3020 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
3022 case SECURITY_SYSTEM:
3023 case SECURITY_ADMINISTRATOR:
3024 break;
3025 default:
3026 /* Users and annonymous are not allowed to access secrets */
3027 return NT_STATUS_ACCESS_DENIED;
3030 secret_state = talloc(mem_ctx, struct lsa_secret_state);
3031 if (!secret_state) {
3032 return NT_STATUS_NO_MEMORY;
3034 secret_state->policy = policy_state;
3036 if (strncmp("G$", r->in.name.string, 2) == 0) {
3037 name = &r->in.name.string[2];
3038 /* 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) */
3039 secret_state->sam_ldb = talloc_reference(secret_state,
3040 samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(dce_call->conn->dce_ctx->lp_ctx)));
3041 secret_state->global = true;
3043 if (strlen(name) < 1) {
3044 return NT_STATUS_INVALID_PARAMETER;
3047 /* search for the secret record */
3048 ret = gendb_search(secret_state->sam_ldb,
3049 mem_ctx, policy_state->system_dn, &msgs, attrs,
3050 "(&(cn=%s Secret)(objectclass=secret))",
3051 ldb_binary_encode_string(mem_ctx, name));
3052 if (ret == 0) {
3053 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3056 if (ret != 1) {
3057 DEBUG(0,("Found %d records matching DN %s\n", ret,
3058 ldb_dn_get_linearized(policy_state->system_dn)));
3059 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3062 } else {
3063 secret_state->global = false;
3064 secret_state->sam_ldb = talloc_reference(secret_state,
3065 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
3067 name = r->in.name.string;
3068 if (strlen(name) < 1) {
3069 return NT_STATUS_INVALID_PARAMETER;
3072 /* search for the secret record */
3073 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
3074 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
3075 &msgs, attrs,
3076 "(&(cn=%s)(objectclass=secret))",
3077 ldb_binary_encode_string(mem_ctx, name));
3078 if (ret == 0) {
3079 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3082 if (ret != 1) {
3083 DEBUG(0,("Found %d records matching CN=%s\n",
3084 ret, ldb_binary_encode_string(mem_ctx, name)));
3085 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3089 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
3091 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
3092 if (!handle) {
3093 return NT_STATUS_NO_MEMORY;
3096 handle->data = talloc_steal(handle, secret_state);
3098 secret_state->access_mask = r->in.access_mask;
3099 secret_state->policy = talloc_reference(secret_state, policy_state);
3101 *r->out.sec_handle = handle->wire_handle;
3103 return NT_STATUS_OK;
3108 lsa_SetSecret
3110 static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3111 struct lsa_SetSecret *r)
3114 struct dcesrv_handle *h;
3115 struct lsa_secret_state *secret_state;
3116 struct ldb_message *msg;
3117 DATA_BLOB session_key;
3118 DATA_BLOB crypt_secret, secret;
3119 struct ldb_val val;
3120 int ret;
3121 NTSTATUS status = NT_STATUS_OK;
3123 struct timeval now = timeval_current();
3124 NTTIME nt_now = timeval_to_nttime(&now);
3126 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
3128 secret_state = h->data;
3130 msg = ldb_msg_new(mem_ctx);
3131 if (msg == NULL) {
3132 return NT_STATUS_NO_MEMORY;
3135 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
3136 if (!msg->dn) {
3137 return NT_STATUS_NO_MEMORY;
3139 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
3140 if (!NT_STATUS_IS_OK(status)) {
3141 return status;
3144 if (r->in.old_val) {
3145 /* Decrypt */
3146 crypt_secret.data = r->in.old_val->data;
3147 crypt_secret.length = r->in.old_val->size;
3149 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
3150 if (!NT_STATUS_IS_OK(status)) {
3151 return status;
3154 val.data = secret.data;
3155 val.length = secret.length;
3157 /* set value */
3158 if (samdb_msg_add_value(secret_state->sam_ldb,
3159 mem_ctx, msg, "priorValue", &val) != LDB_SUCCESS) {
3160 return NT_STATUS_NO_MEMORY;
3163 /* set old value mtime */
3164 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3165 mem_ctx, msg, "priorSetTime", nt_now) != LDB_SUCCESS) {
3166 return NT_STATUS_NO_MEMORY;
3169 } else {
3170 /* If the old value is not set, then migrate the
3171 * current value to the old value */
3172 const struct ldb_val *old_val;
3173 NTTIME last_set_time;
3174 struct ldb_message **res;
3175 const char *attrs[] = {
3176 "currentValue",
3177 "lastSetTime",
3178 NULL
3181 /* search for the secret record */
3182 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
3183 secret_state->secret_dn, &res, attrs);
3184 if (ret == 0) {
3185 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3188 if (ret != 1) {
3189 DEBUG(0,("Found %d records matching dn=%s\n", ret,
3190 ldb_dn_get_linearized(secret_state->secret_dn)));
3191 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3194 old_val = ldb_msg_find_ldb_val(res[0], "currentValue");
3195 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
3197 if (old_val) {
3198 /* set old value */
3199 if (samdb_msg_add_value(secret_state->sam_ldb,
3200 mem_ctx, msg, "priorValue",
3201 old_val) != 0) {
3202 return NT_STATUS_NO_MEMORY;
3204 } else {
3205 if (samdb_msg_add_delete(secret_state->sam_ldb,
3206 mem_ctx, msg, "priorValue")) {
3207 return NT_STATUS_NO_MEMORY;
3212 /* set old value mtime */
3213 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
3214 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3215 mem_ctx, msg, "priorSetTime", last_set_time) != LDB_SUCCESS) {
3216 return NT_STATUS_NO_MEMORY;
3218 } else {
3219 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3220 mem_ctx, msg, "priorSetTime", nt_now) != LDB_SUCCESS) {
3221 return NT_STATUS_NO_MEMORY;
3226 if (r->in.new_val) {
3227 /* Decrypt */
3228 crypt_secret.data = r->in.new_val->data;
3229 crypt_secret.length = r->in.new_val->size;
3231 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
3232 if (!NT_STATUS_IS_OK(status)) {
3233 return status;
3236 val.data = secret.data;
3237 val.length = secret.length;
3239 /* set value */
3240 if (samdb_msg_add_value(secret_state->sam_ldb,
3241 mem_ctx, msg, "currentValue", &val) != LDB_SUCCESS) {
3242 return NT_STATUS_NO_MEMORY;
3245 /* set new value mtime */
3246 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3247 mem_ctx, msg, "lastSetTime", nt_now) != LDB_SUCCESS) {
3248 return NT_STATUS_NO_MEMORY;
3251 } else {
3252 /* NULL out the NEW value */
3253 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3254 mem_ctx, msg, "lastSetTime", nt_now) != LDB_SUCCESS) {
3255 return NT_STATUS_NO_MEMORY;
3257 if (samdb_msg_add_delete(secret_state->sam_ldb,
3258 mem_ctx, msg, "currentValue") != LDB_SUCCESS) {
3259 return NT_STATUS_NO_MEMORY;
3263 /* modify the samdb record */
3264 ret = dsdb_replace(secret_state->sam_ldb, msg, 0);
3265 if (ret != LDB_SUCCESS) {
3266 /* we really need samdb.c to return NTSTATUS */
3267 return NT_STATUS_UNSUCCESSFUL;
3270 return NT_STATUS_OK;
3275 lsa_QuerySecret
3277 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3278 struct lsa_QuerySecret *r)
3280 struct dcesrv_handle *h;
3281 struct lsa_secret_state *secret_state;
3282 struct ldb_message *msg;
3283 DATA_BLOB session_key;
3284 DATA_BLOB crypt_secret, secret;
3285 int ret;
3286 struct ldb_message **res;
3287 const char *attrs[] = {
3288 "currentValue",
3289 "priorValue",
3290 "lastSetTime",
3291 "priorSetTime",
3292 NULL
3295 NTSTATUS nt_status;
3297 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
3299 /* Ensure user is permitted to read this... */
3300 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
3302 case SECURITY_SYSTEM:
3303 case SECURITY_ADMINISTRATOR:
3304 break;
3305 default:
3306 /* Users and annonymous are not allowed to read secrets */
3307 return NT_STATUS_ACCESS_DENIED;
3310 secret_state = h->data;
3312 /* pull all the user attributes */
3313 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
3314 secret_state->secret_dn, &res, attrs);
3315 if (ret != 1) {
3316 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3318 msg = res[0];
3320 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
3321 if (!NT_STATUS_IS_OK(nt_status)) {
3322 return nt_status;
3325 if (r->in.old_val) {
3326 const struct ldb_val *prior_val;
3327 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
3328 if (!r->out.old_val) {
3329 return NT_STATUS_NO_MEMORY;
3331 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
3333 if (prior_val && prior_val->length) {
3334 secret.data = prior_val->data;
3335 secret.length = prior_val->length;
3337 /* Encrypt */
3338 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
3339 if (!crypt_secret.length) {
3340 return NT_STATUS_NO_MEMORY;
3342 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
3343 if (!r->out.old_val->buf) {
3344 return NT_STATUS_NO_MEMORY;
3346 r->out.old_val->buf->size = crypt_secret.length;
3347 r->out.old_val->buf->length = crypt_secret.length;
3348 r->out.old_val->buf->data = crypt_secret.data;
3352 if (r->in.old_mtime) {
3353 r->out.old_mtime = talloc(mem_ctx, NTTIME);
3354 if (!r->out.old_mtime) {
3355 return NT_STATUS_NO_MEMORY;
3357 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
3360 if (r->in.new_val) {
3361 const struct ldb_val *new_val;
3362 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
3363 if (!r->out.new_val) {
3364 return NT_STATUS_NO_MEMORY;
3367 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
3369 if (new_val && new_val->length) {
3370 secret.data = new_val->data;
3371 secret.length = new_val->length;
3373 /* Encrypt */
3374 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
3375 if (!crypt_secret.length) {
3376 return NT_STATUS_NO_MEMORY;
3378 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
3379 if (!r->out.new_val->buf) {
3380 return NT_STATUS_NO_MEMORY;
3382 r->out.new_val->buf->length = crypt_secret.length;
3383 r->out.new_val->buf->size = crypt_secret.length;
3384 r->out.new_val->buf->data = crypt_secret.data;
3388 if (r->in.new_mtime) {
3389 r->out.new_mtime = talloc(mem_ctx, NTTIME);
3390 if (!r->out.new_mtime) {
3391 return NT_STATUS_NO_MEMORY;
3393 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
3396 return NT_STATUS_OK;
3401 lsa_LookupPrivValue
3403 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
3404 TALLOC_CTX *mem_ctx,
3405 struct lsa_LookupPrivValue *r)
3407 struct dcesrv_handle *h;
3408 struct lsa_policy_state *state;
3409 int id;
3411 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3413 state = h->data;
3415 id = sec_privilege_id(r->in.name->string);
3416 if (id == -1) {
3417 return NT_STATUS_NO_SUCH_PRIVILEGE;
3420 r->out.luid->low = id;
3421 r->out.luid->high = 0;
3423 return NT_STATUS_OK;
3428 lsa_LookupPrivName
3430 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
3431 TALLOC_CTX *mem_ctx,
3432 struct lsa_LookupPrivName *r)
3434 struct dcesrv_handle *h;
3435 struct lsa_policy_state *state;
3436 struct lsa_StringLarge *name;
3437 const char *privname;
3439 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3441 state = h->data;
3443 if (r->in.luid->high != 0) {
3444 return NT_STATUS_NO_SUCH_PRIVILEGE;
3447 privname = sec_privilege_name(r->in.luid->low);
3448 if (privname == NULL) {
3449 return NT_STATUS_NO_SUCH_PRIVILEGE;
3452 name = talloc(mem_ctx, struct lsa_StringLarge);
3453 if (name == NULL) {
3454 return NT_STATUS_NO_MEMORY;
3457 name->string = privname;
3459 *r->out.name = name;
3461 return NT_STATUS_OK;
3466 lsa_LookupPrivDisplayName
3468 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
3469 TALLOC_CTX *mem_ctx,
3470 struct lsa_LookupPrivDisplayName *r)
3472 struct dcesrv_handle *h;
3473 struct lsa_policy_state *state;
3474 struct lsa_StringLarge *disp_name = NULL;
3475 int id;
3477 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3479 state = h->data;
3481 id = sec_privilege_id(r->in.name->string);
3482 if (id == -1) {
3483 return NT_STATUS_NO_SUCH_PRIVILEGE;
3486 disp_name = talloc(mem_ctx, struct lsa_StringLarge);
3487 if (disp_name == NULL) {
3488 return NT_STATUS_NO_MEMORY;
3491 disp_name->string = sec_privilege_display_name(id, &r->in.language_id);
3492 if (disp_name->string == NULL) {
3493 return NT_STATUS_INTERNAL_ERROR;
3496 *r->out.disp_name = disp_name;
3497 *r->out.returned_language_id = 0;
3499 return NT_STATUS_OK;
3504 lsa_EnumAccountsWithUserRight
3506 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
3507 TALLOC_CTX *mem_ctx,
3508 struct lsa_EnumAccountsWithUserRight *r)
3510 struct dcesrv_handle *h;
3511 struct lsa_policy_state *state;
3512 int ret, i;
3513 struct ldb_message **res;
3514 const char * const attrs[] = { "objectSid", NULL};
3515 const char *privname;
3517 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3519 state = h->data;
3521 if (r->in.name == NULL) {
3522 return NT_STATUS_NO_SUCH_PRIVILEGE;
3525 privname = r->in.name->string;
3526 if (sec_privilege_id(privname) == -1) {
3527 return NT_STATUS_NO_SUCH_PRIVILEGE;
3530 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
3531 "privilege=%s", privname);
3532 if (ret < 0) {
3533 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3535 if (ret == 0) {
3536 return NT_STATUS_NO_MORE_ENTRIES;
3539 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
3540 if (r->out.sids->sids == NULL) {
3541 return NT_STATUS_NO_MEMORY;
3543 for (i=0;i<ret;i++) {
3544 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
3545 res[i], "objectSid");
3546 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
3548 r->out.sids->num_sids = ret;
3550 return NT_STATUS_OK;
3555 lsa_AddAccountRights
3557 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
3558 TALLOC_CTX *mem_ctx,
3559 struct lsa_AddAccountRights *r)
3561 struct dcesrv_handle *h;
3562 struct lsa_policy_state *state;
3564 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3566 state = h->data;
3568 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
3569 LDB_FLAG_MOD_ADD,
3570 r->in.sid, r->in.rights);
3575 lsa_RemoveAccountRights
3577 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
3578 TALLOC_CTX *mem_ctx,
3579 struct lsa_RemoveAccountRights *r)
3581 struct dcesrv_handle *h;
3582 struct lsa_policy_state *state;
3584 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3586 state = h->data;
3588 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
3589 LDB_FLAG_MOD_DELETE,
3590 r->in.sid, r->in.rights);
3595 lsa_StorePrivateData
3597 static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3598 struct lsa_StorePrivateData *r)
3600 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3605 lsa_RetrievePrivateData
3607 static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3608 struct lsa_RetrievePrivateData *r)
3610 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3615 lsa_GetUserName
3617 static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3618 struct lsa_GetUserName *r)
3620 NTSTATUS status = NT_STATUS_OK;
3621 const char *account_name;
3622 const char *authority_name;
3623 struct lsa_String *_account_name;
3624 struct lsa_String *_authority_name = NULL;
3626 /* this is what w2k3 does */
3627 r->out.account_name = r->in.account_name;
3628 r->out.authority_name = r->in.authority_name;
3630 if (r->in.account_name
3631 && *r->in.account_name
3632 /* && *(*r->in.account_name)->string */
3634 return NT_STATUS_INVALID_PARAMETER;
3637 if (r->in.authority_name
3638 && *r->in.authority_name
3639 /* && *(*r->in.authority_name)->string */
3641 return NT_STATUS_INVALID_PARAMETER;
3644 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
3645 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
3647 _account_name = talloc(mem_ctx, struct lsa_String);
3648 NT_STATUS_HAVE_NO_MEMORY(_account_name);
3649 _account_name->string = account_name;
3651 if (r->in.authority_name) {
3652 _authority_name = talloc(mem_ctx, struct lsa_String);
3653 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
3654 _authority_name->string = authority_name;
3657 *r->out.account_name = _account_name;
3658 if (r->out.authority_name) {
3659 *r->out.authority_name = _authority_name;
3662 return status;
3666 lsa_SetInfoPolicy2
3668 static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
3669 TALLOC_CTX *mem_ctx,
3670 struct lsa_SetInfoPolicy2 *r)
3672 /* need to support these */
3673 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3677 lsa_QueryDomainInformationPolicy
3679 static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
3680 TALLOC_CTX *mem_ctx,
3681 struct lsa_QueryDomainInformationPolicy *r)
3683 union lsa_DomainInformationPolicy *info;
3685 info = talloc(r->out.info, union lsa_DomainInformationPolicy);
3686 if (!info) {
3687 return NT_STATUS_NO_MEMORY;
3690 switch (r->in.level) {
3691 case LSA_DOMAIN_INFO_POLICY_EFS:
3692 talloc_free(info);
3693 *r->out.info = NULL;
3694 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3695 case LSA_DOMAIN_INFO_POLICY_KERBEROS:
3697 struct lsa_DomainInfoKerberos *k = &info->kerberos_info;
3698 struct smb_krb5_context *smb_krb5_context;
3699 int ret = smb_krb5_init_context(mem_ctx,
3700 dce_call->event_ctx,
3701 dce_call->conn->dce_ctx->lp_ctx,
3702 &smb_krb5_context);
3703 if (ret != 0) {
3704 talloc_free(info);
3705 *r->out.info = NULL;
3706 return NT_STATUS_INTERNAL_ERROR;
3708 k->enforce_restrictions = 0; /* FIXME, details missing from MS-LSAD 2.2.53 */
3709 k->service_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
3710 k->user_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
3711 k->user_tkt_renewaltime = 0; /* Need to find somewhere to store this, and query in KDC too */
3712 k->clock_skew = krb5_get_max_time_skew(smb_krb5_context->krb5_context);
3713 talloc_free(smb_krb5_context);
3714 *r->out.info = info;
3715 return NT_STATUS_OK;
3717 default:
3718 talloc_free(info);
3719 *r->out.info = NULL;
3720 return NT_STATUS_INVALID_INFO_CLASS;
3725 lsa_SetDomInfoPolicy
3727 static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
3728 TALLOC_CTX *mem_ctx,
3729 struct lsa_SetDomainInformationPolicy *r)
3731 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3735 lsa_TestCall
3737 static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
3738 TALLOC_CTX *mem_ctx,
3739 struct lsa_TestCall *r)
3741 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3745 lsa_CREDRWRITE
3747 static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3748 struct lsa_CREDRWRITE *r)
3750 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3755 lsa_CREDRREAD
3757 static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3758 struct lsa_CREDRREAD *r)
3760 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3765 lsa_CREDRENUMERATE
3767 static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3768 struct lsa_CREDRENUMERATE *r)
3770 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3775 lsa_CREDRWRITEDOMAINCREDENTIALS
3777 static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3778 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3780 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3785 lsa_CREDRREADDOMAINCREDENTIALS
3787 static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3788 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3790 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3795 lsa_CREDRDELETE
3797 static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3798 struct lsa_CREDRDELETE *r)
3800 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3805 lsa_CREDRGETTARGETINFO
3807 static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3808 struct lsa_CREDRGETTARGETINFO *r)
3810 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3815 lsa_CREDRPROFILELOADED
3817 static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3818 struct lsa_CREDRPROFILELOADED *r)
3820 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3825 lsa_CREDRGETSESSIONTYPES
3827 static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3828 struct lsa_CREDRGETSESSIONTYPES *r)
3830 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3835 lsa_LSARREGISTERAUDITEVENT
3837 static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3838 struct lsa_LSARREGISTERAUDITEVENT *r)
3840 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3845 lsa_LSARGENAUDITEVENT
3847 static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3848 struct lsa_LSARGENAUDITEVENT *r)
3850 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3855 lsa_LSARUNREGISTERAUDITEVENT
3857 static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3858 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3860 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3865 lsa_lsaRQueryForestTrustInformation
3867 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3868 struct lsa_lsaRQueryForestTrustInformation *r)
3870 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3875 lsa_lsaRSetForestTrustInformation
3877 static NTSTATUS dcesrv_lsa_lsaRSetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3878 struct lsa_lsaRSetForestTrustInformation *r)
3880 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3885 lsa_CREDRRENAME
3887 static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3888 struct lsa_CREDRRENAME *r)
3890 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3896 lsa_LSAROPENPOLICYSCE
3898 static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3899 struct lsa_LSAROPENPOLICYSCE *r)
3901 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3906 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
3908 static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3909 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
3911 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3916 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
3918 static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3919 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
3921 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3926 lsa_LSARADTREPORTSECURITYEVENT
3928 static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3929 struct lsa_LSARADTREPORTSECURITYEVENT *r)
3931 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3935 /* include the generated boilerplate */
3936 #include "librpc/gen_ndr/ndr_lsa_s.c"
3940 /*****************************************
3941 NOTE! The remaining calls below were
3942 removed in w2k3, so the DCESRV_FAULT()
3943 replies are the correct implementation. Do
3944 not try and fill these in with anything else
3945 ******************************************/
3948 dssetup_DsRoleDnsNameToFlatName
3950 static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3951 struct dssetup_DsRoleDnsNameToFlatName *r)
3953 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3958 dssetup_DsRoleDcAsDc
3960 static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3961 struct dssetup_DsRoleDcAsDc *r)
3963 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3968 dssetup_DsRoleDcAsReplica
3970 static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3971 struct dssetup_DsRoleDcAsReplica *r)
3973 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3978 dssetup_DsRoleDemoteDc
3980 static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3981 struct dssetup_DsRoleDemoteDc *r)
3983 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3988 dssetup_DsRoleGetDcOperationProgress
3990 static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3991 struct dssetup_DsRoleGetDcOperationProgress *r)
3993 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3998 dssetup_DsRoleGetDcOperationResults
4000 static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4001 struct dssetup_DsRoleGetDcOperationResults *r)
4003 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4008 dssetup_DsRoleCancel
4010 static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4011 struct dssetup_DsRoleCancel *r)
4013 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4018 dssetup_DsRoleServerSaveStateForUpgrade
4020 static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4021 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
4023 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4028 dssetup_DsRoleUpgradeDownlevelServer
4030 static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4031 struct dssetup_DsRoleUpgradeDownlevelServer *r)
4033 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4038 dssetup_DsRoleAbortDownlevelServerUpgrade
4040 static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4041 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
4043 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4047 /* include the generated boilerplate */
4048 #include "librpc/gen_ndr/ndr_dssetup_s.c"
4050 NTSTATUS dcerpc_server_lsa_init(void)
4052 NTSTATUS ret;
4054 ret = dcerpc_server_dssetup_init();
4055 if (!NT_STATUS_IS_OK(ret)) {
4056 return ret;
4058 ret = dcerpc_server_lsarpc_init();
4059 if (!NT_STATUS_IS_OK(ret)) {
4060 return ret;
4062 return ret;