Use ntvfs session close to close downstream session
[Samba/vfs_proxy.git] / source4 / rpc_server / lsa / dcesrv_lsa.c
blob6507c75ae2c14fa07860925646c93236fbf379de
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 "../lib/util/util_ldb.h"
27 #include "libcli/ldap/ldap_ndr.h"
28 #include "system/kerberos.h"
29 #include "auth/kerberos/kerberos.h"
30 #include "librpc/gen_ndr/ndr_drsblobs.h"
31 #include "librpc/gen_ndr/ndr_lsa.h"
32 #include "../lib/crypto/crypto.h"
35 this type allows us to distinguish handle types
39 state associated with a lsa_OpenAccount() operation
41 struct lsa_account_state {
42 struct lsa_policy_state *policy;
43 uint32_t access_mask;
44 struct dom_sid *account_sid;
49 state associated with a lsa_OpenSecret() operation
51 struct lsa_secret_state {
52 struct lsa_policy_state *policy;
53 uint32_t access_mask;
54 struct ldb_dn *secret_dn;
55 struct ldb_context *sam_ldb;
56 bool global;
60 state associated with a lsa_OpenTrustedDomain() operation
62 struct lsa_trusted_domain_state {
63 struct lsa_policy_state *policy;
64 uint32_t access_mask;
65 struct ldb_dn *trusted_domain_dn;
66 struct ldb_dn *trusted_domain_user_dn;
69 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
70 TALLOC_CTX *mem_ctx,
71 struct lsa_EnumAccountRights *r);
73 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
74 TALLOC_CTX *mem_ctx,
75 struct lsa_policy_state *state,
76 int ldb_flag,
77 struct dom_sid *sid,
78 const struct lsa_RightSet *rights);
80 /*
81 lsa_Close
83 static NTSTATUS dcesrv_lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
84 struct lsa_Close *r)
86 struct dcesrv_handle *h;
88 *r->out.handle = *r->in.handle;
90 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
92 talloc_free(h);
94 ZERO_STRUCTP(r->out.handle);
96 return NT_STATUS_OK;
101 lsa_Delete
103 static NTSTATUS dcesrv_lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
104 struct lsa_Delete *r)
106 return NT_STATUS_NOT_SUPPORTED;
111 lsa_DeleteObject
113 static NTSTATUS dcesrv_lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
114 struct lsa_DeleteObject *r)
116 struct dcesrv_handle *h;
117 int ret;
119 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
121 if (h->wire_handle.handle_type == LSA_HANDLE_SECRET) {
122 struct lsa_secret_state *secret_state = h->data;
124 /* Ensure user is permitted to delete this... */
125 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
127 case SECURITY_SYSTEM:
128 case SECURITY_ADMINISTRATOR:
129 break;
130 default:
131 /* Users and annonymous are not allowed delete things */
132 return NT_STATUS_ACCESS_DENIED;
135 ret = ldb_delete(secret_state->sam_ldb,
136 secret_state->secret_dn);
137 talloc_free(h);
138 if (ret != 0) {
139 return NT_STATUS_INVALID_HANDLE;
142 ZERO_STRUCTP(r->out.handle);
144 return NT_STATUS_OK;
145 } else if (h->wire_handle.handle_type == LSA_HANDLE_TRUSTED_DOMAIN) {
146 struct lsa_trusted_domain_state *trusted_domain_state =
147 talloc_get_type(h->data, struct lsa_trusted_domain_state);
148 ret = ldb_transaction_start(trusted_domain_state->policy->sam_ldb);
149 if (ret != 0) {
150 return NT_STATUS_INTERNAL_DB_CORRUPTION;
153 ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
154 trusted_domain_state->trusted_domain_dn);
155 if (ret != 0) {
156 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
157 return NT_STATUS_INVALID_HANDLE;
160 if (trusted_domain_state->trusted_domain_user_dn) {
161 ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
162 trusted_domain_state->trusted_domain_user_dn);
163 if (ret != 0) {
164 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
165 return NT_STATUS_INVALID_HANDLE;
169 ret = ldb_transaction_commit(trusted_domain_state->policy->sam_ldb);
170 if (ret != 0) {
171 return NT_STATUS_INTERNAL_DB_CORRUPTION;
173 talloc_free(h);
174 ZERO_STRUCTP(r->out.handle);
176 return NT_STATUS_OK;
177 } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
178 struct lsa_RightSet *rights;
179 struct lsa_account_state *astate;
180 struct lsa_EnumAccountRights r2;
181 NTSTATUS status;
183 rights = talloc(mem_ctx, struct lsa_RightSet);
185 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
187 astate = h->data;
189 r2.in.handle = &astate->policy->handle->wire_handle;
190 r2.in.sid = astate->account_sid;
191 r2.out.rights = rights;
193 /* dcesrv_lsa_EnumAccountRights takes a LSA_HANDLE_POLICY,
194 but we have a LSA_HANDLE_ACCOUNT here, so this call
195 will always fail */
196 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
197 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
198 return NT_STATUS_OK;
201 if (!NT_STATUS_IS_OK(status)) {
202 return status;
205 status = dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
206 LDB_FLAG_MOD_DELETE, astate->account_sid,
207 r2.out.rights);
208 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
209 return NT_STATUS_OK;
212 if (!NT_STATUS_IS_OK(status)) {
213 return status;
216 ZERO_STRUCTP(r->out.handle);
219 return NT_STATUS_INVALID_HANDLE;
224 lsa_EnumPrivs
226 static NTSTATUS dcesrv_lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
227 struct lsa_EnumPrivs *r)
229 struct dcesrv_handle *h;
230 struct lsa_policy_state *state;
231 int i;
232 const char *privname;
234 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
236 state = h->data;
238 i = *r->in.resume_handle;
239 if (i == 0) i = 1;
241 while ((privname = sec_privilege_name(i)) &&
242 r->out.privs->count < r->in.max_count) {
243 struct lsa_PrivEntry *e;
245 r->out.privs->privs = talloc_realloc(r->out.privs,
246 r->out.privs->privs,
247 struct lsa_PrivEntry,
248 r->out.privs->count+1);
249 if (r->out.privs->privs == NULL) {
250 return NT_STATUS_NO_MEMORY;
252 e = &r->out.privs->privs[r->out.privs->count];
253 e->luid.low = i;
254 e->luid.high = 0;
255 e->name.string = privname;
256 r->out.privs->count++;
257 i++;
260 *r->out.resume_handle = i;
262 return NT_STATUS_OK;
267 lsa_QuerySecObj
269 static NTSTATUS dcesrv_lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
270 struct lsa_QuerySecurity *r)
272 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
277 lsa_SetSecObj
279 static NTSTATUS dcesrv_lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
280 struct lsa_SetSecObj *r)
282 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
287 lsa_ChangePassword
289 static NTSTATUS dcesrv_lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
290 struct lsa_ChangePassword *r)
292 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
296 dssetup_DsRoleGetPrimaryDomainInformation
298 This is not an LSA call, but is the only call left on the DSSETUP
299 pipe (after the pipe was truncated), and needs lsa_get_policy_state
301 static WERROR dcesrv_dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state *dce_call,
302 TALLOC_CTX *mem_ctx,
303 struct dssetup_DsRoleGetPrimaryDomainInformation *r)
305 union dssetup_DsRoleInfo *info;
307 info = talloc(mem_ctx, union dssetup_DsRoleInfo);
308 W_ERROR_HAVE_NO_MEMORY(info);
310 switch (r->in.level) {
311 case DS_ROLE_BASIC_INFORMATION:
313 enum dssetup_DsRole role = DS_ROLE_STANDALONE_SERVER;
314 uint32_t flags = 0;
315 const char *domain = NULL;
316 const char *dns_domain = NULL;
317 const char *forest = NULL;
318 struct GUID domain_guid;
319 struct lsa_policy_state *state;
321 NTSTATUS status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
322 if (!NT_STATUS_IS_OK(status)) {
323 return ntstatus_to_werror(status);
326 ZERO_STRUCT(domain_guid);
328 switch (lp_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
329 case ROLE_STANDALONE:
330 role = DS_ROLE_STANDALONE_SERVER;
331 break;
332 case ROLE_DOMAIN_MEMBER:
333 role = DS_ROLE_MEMBER_SERVER;
334 break;
335 case ROLE_DOMAIN_CONTROLLER:
336 if (samdb_is_pdc(state->sam_ldb)) {
337 role = DS_ROLE_PRIMARY_DC;
338 } else {
339 role = DS_ROLE_BACKUP_DC;
341 break;
344 switch (lp_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
345 case ROLE_STANDALONE:
346 domain = talloc_strdup(mem_ctx, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx));
347 W_ERROR_HAVE_NO_MEMORY(domain);
348 break;
349 case ROLE_DOMAIN_MEMBER:
350 domain = talloc_strdup(mem_ctx, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx));
351 W_ERROR_HAVE_NO_MEMORY(domain);
352 /* TODO: what is with dns_domain and forest and guid? */
353 break;
354 case ROLE_DOMAIN_CONTROLLER:
355 flags = DS_ROLE_PRIMARY_DS_RUNNING;
357 if (state->mixed_domain == 1) {
358 flags |= DS_ROLE_PRIMARY_DS_MIXED_MODE;
361 domain = state->domain_name;
362 dns_domain = state->domain_dns;
363 forest = state->forest_dns;
365 domain_guid = state->domain_guid;
366 flags |= DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT;
367 break;
370 info->basic.role = role;
371 info->basic.flags = flags;
372 info->basic.domain = domain;
373 info->basic.dns_domain = dns_domain;
374 info->basic.forest = forest;
375 info->basic.domain_guid = domain_guid;
377 r->out.info = info;
378 return WERR_OK;
380 case DS_ROLE_UPGRADE_STATUS:
382 info->upgrade.upgrading = DS_ROLE_NOT_UPGRADING;
383 info->upgrade.previous_role = DS_ROLE_PREVIOUS_UNKNOWN;
385 r->out.info = info;
386 return WERR_OK;
388 case DS_ROLE_OP_STATUS:
390 info->opstatus.status = DS_ROLE_OP_IDLE;
392 r->out.info = info;
393 return WERR_OK;
395 default:
396 return WERR_INVALID_PARAM;
399 return WERR_INVALID_PARAM;
403 fill in the AccountDomain info
405 static NTSTATUS dcesrv_lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
406 struct lsa_DomainInfo *info)
408 info->name.string = state->domain_name;
409 info->sid = state->domain_sid;
411 return NT_STATUS_OK;
415 fill in the DNS domain info
417 static NTSTATUS dcesrv_lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
418 struct lsa_DnsDomainInfo *info)
420 info->name.string = state->domain_name;
421 info->sid = state->domain_sid;
422 info->dns_domain.string = state->domain_dns;
423 info->dns_forest.string = state->forest_dns;
424 info->domain_guid = state->domain_guid;
426 return NT_STATUS_OK;
430 lsa_QueryInfoPolicy2
432 static NTSTATUS dcesrv_lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
433 struct lsa_QueryInfoPolicy2 *r)
435 struct lsa_policy_state *state;
436 struct dcesrv_handle *h;
437 union lsa_PolicyInformation *info;
439 *r->out.info = NULL;
441 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
443 state = h->data;
445 info = talloc_zero(mem_ctx, union lsa_PolicyInformation);
446 if (!info) {
447 return NT_STATUS_NO_MEMORY;
449 *r->out.info = info;
451 switch (r->in.level) {
452 case LSA_POLICY_INFO_AUDIT_LOG:
453 /* we don't need to fill in any of this */
454 ZERO_STRUCT(info->audit_log);
455 return NT_STATUS_OK;
456 case LSA_POLICY_INFO_AUDIT_EVENTS:
457 /* we don't need to fill in any of this */
458 ZERO_STRUCT(info->audit_events);
459 return NT_STATUS_OK;
460 case LSA_POLICY_INFO_PD:
461 /* we don't need to fill in any of this */
462 ZERO_STRUCT(info->pd);
463 return NT_STATUS_OK;
465 case LSA_POLICY_INFO_DOMAIN:
466 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->domain);
467 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
468 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->account_domain);
469 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
470 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->l_account_domain);
473 case LSA_POLICY_INFO_ROLE:
474 info->role.role = LSA_ROLE_PRIMARY;
475 return NT_STATUS_OK;
477 case LSA_POLICY_INFO_DNS:
478 case LSA_POLICY_INFO_DNS_INT:
479 return dcesrv_lsa_info_DNS(state, mem_ctx, &info->dns);
481 case LSA_POLICY_INFO_REPLICA:
482 ZERO_STRUCT(info->replica);
483 return NT_STATUS_OK;
485 case LSA_POLICY_INFO_QUOTA:
486 ZERO_STRUCT(info->quota);
487 return NT_STATUS_OK;
489 case LSA_POLICY_INFO_MOD:
490 case LSA_POLICY_INFO_AUDIT_FULL_SET:
491 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
492 /* windows gives INVALID_PARAMETER */
493 *r->out.info = NULL;
494 return NT_STATUS_INVALID_PARAMETER;
497 *r->out.info = NULL;
498 return NT_STATUS_INVALID_INFO_CLASS;
502 lsa_QueryInfoPolicy
504 static NTSTATUS dcesrv_lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
505 struct lsa_QueryInfoPolicy *r)
507 struct lsa_QueryInfoPolicy2 r2;
508 NTSTATUS status;
510 ZERO_STRUCT(r2);
512 r2.in.handle = r->in.handle;
513 r2.in.level = r->in.level;
514 r2.out.info = r->out.info;
516 status = dcesrv_lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
518 return status;
522 lsa_SetInfoPolicy
524 static NTSTATUS dcesrv_lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
525 struct lsa_SetInfoPolicy *r)
527 /* need to support this */
528 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
533 lsa_ClearAuditLog
535 static NTSTATUS dcesrv_lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
536 struct lsa_ClearAuditLog *r)
538 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
543 lsa_CreateAccount
545 This call does not seem to have any long-term effects, hence no database operations
547 we need to talk to the MS product group to find out what this account database means!
549 answer is that the lsa database is totally separate from the SAM and
550 ldap databases. We are going to need a separate ldb to store these
551 accounts. The SIDs on this account bear no relation to the SIDs in
554 static NTSTATUS dcesrv_lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
555 struct lsa_CreateAccount *r)
557 struct lsa_account_state *astate;
559 struct lsa_policy_state *state;
560 struct dcesrv_handle *h, *ah;
562 ZERO_STRUCTP(r->out.acct_handle);
564 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
566 state = h->data;
568 astate = talloc(dce_call->conn, struct lsa_account_state);
569 if (astate == NULL) {
570 return NT_STATUS_NO_MEMORY;
573 astate->account_sid = dom_sid_dup(astate, r->in.sid);
574 if (astate->account_sid == NULL) {
575 talloc_free(astate);
576 return NT_STATUS_NO_MEMORY;
579 astate->policy = talloc_reference(astate, state);
580 astate->access_mask = r->in.access_mask;
582 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
583 if (!ah) {
584 talloc_free(astate);
585 return NT_STATUS_NO_MEMORY;
588 ah->data = talloc_steal(ah, astate);
590 *r->out.acct_handle = ah->wire_handle;
592 return NT_STATUS_OK;
597 lsa_EnumAccounts
599 static NTSTATUS dcesrv_lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
600 struct lsa_EnumAccounts *r)
602 struct dcesrv_handle *h;
603 struct lsa_policy_state *state;
604 int ret, i;
605 struct ldb_message **res;
606 const char * const attrs[] = { "objectSid", NULL};
607 uint32_t count;
609 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
611 state = h->data;
613 /* NOTE: This call must only return accounts that have at least
614 one privilege set
616 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
617 "(&(objectSid=*)(privilege=*))");
618 if (ret < 0) {
619 return NT_STATUS_NO_SUCH_USER;
622 if (*r->in.resume_handle >= ret) {
623 return NT_STATUS_NO_MORE_ENTRIES;
626 count = ret - *r->in.resume_handle;
627 if (count > r->in.num_entries) {
628 count = r->in.num_entries;
631 if (count == 0) {
632 return NT_STATUS_NO_MORE_ENTRIES;
635 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, count);
636 if (r->out.sids->sids == NULL) {
637 return NT_STATUS_NO_MEMORY;
640 for (i=0;i<count;i++) {
641 r->out.sids->sids[i].sid =
642 samdb_result_dom_sid(r->out.sids->sids,
643 res[i + *r->in.resume_handle],
644 "objectSid");
645 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
648 r->out.sids->num_sids = count;
649 *r->out.resume_handle = count + *r->in.resume_handle;
651 return NT_STATUS_OK;
657 lsa_CreateTrustedDomainEx2
659 static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dce_call,
660 TALLOC_CTX *mem_ctx,
661 struct lsa_CreateTrustedDomainEx2 *r,
662 int op)
664 struct dcesrv_handle *policy_handle;
665 struct lsa_policy_state *policy_state;
666 struct lsa_trusted_domain_state *trusted_domain_state;
667 struct dcesrv_handle *handle;
668 struct ldb_message **msgs, *msg, *msg_user;
669 const char *attrs[] = {
670 NULL
672 const char *netbios_name;
673 const char *dns_name;
674 const char *name;
675 DATA_BLOB session_key = data_blob(NULL, 0);
676 DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob;
677 struct trustDomainPasswords auth_struct;
678 int ret;
679 NTSTATUS nt_status;
680 enum ndr_err_code ndr_err;
682 DCESRV_PULL_HANDLE(policy_handle, r->in.policy_handle, LSA_HANDLE_POLICY);
683 ZERO_STRUCTP(r->out.trustdom_handle);
685 policy_state = policy_handle->data;
687 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
688 if (!NT_STATUS_IS_OK(nt_status)) {
689 return nt_status;
692 netbios_name = r->in.info->netbios_name.string;
693 if (!netbios_name) {
694 return NT_STATUS_INVALID_PARAMETER;
697 dns_name = r->in.info->domain_name.string;
699 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
700 if (!trusted_domain_state) {
701 return NT_STATUS_NO_MEMORY;
703 trusted_domain_state->policy = policy_state;
705 if (strcasecmp(netbios_name, "BUILTIN") == 0
706 || (dns_name && strcasecmp(dns_name, "BUILTIN") == 0)
707 || (dom_sid_in_domain(policy_state->builtin_sid, r->in.info->sid))) {
708 return NT_STATUS_INVALID_PARAMETER;;
711 if (strcasecmp(netbios_name, policy_state->domain_name) == 0
712 || strcasecmp(netbios_name, policy_state->domain_dns) == 0
713 || (dns_name && strcasecmp(dns_name, policy_state->domain_dns) == 0)
714 || (dns_name && strcasecmp(dns_name, policy_state->domain_name) == 0)
715 || (dom_sid_equal(policy_state->domain_sid, r->in.info->sid))) {
716 return NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED;
719 /* While this is a REF pointer, some of the functions that wrap this don't provide this */
720 if (op == NDR_LSA_CREATETRUSTEDDOMAIN) {
721 /* No secrets are created at this time, for this function */
722 auth_struct.outgoing.count = 0;
723 auth_struct.incoming.count = 0;
724 } else {
725 auth_blob = data_blob_const(r->in.auth_info->auth_blob.data, r->in.auth_info->auth_blob.size);
726 arcfour_crypt_blob(auth_blob.data, auth_blob.length, &session_key);
727 ndr_err = ndr_pull_struct_blob(&auth_blob, mem_ctx,
728 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
729 &auth_struct,
730 (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
731 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
732 return NT_STATUS_INVALID_PARAMETER;
735 if (op == NDR_LSA_CREATETRUSTEDDOMAINEX) {
736 if (auth_struct.incoming.count > 1) {
737 return NT_STATUS_INVALID_PARAMETER;
742 if (auth_struct.incoming.count) {
743 int i;
744 struct trustAuthInOutBlob incoming;
746 incoming.count = auth_struct.incoming.count;
747 incoming.current = talloc(mem_ctx, struct AuthenticationInformationArray);
748 if (!incoming.current) {
749 return NT_STATUS_NO_MEMORY;
752 incoming.current->array = *auth_struct.incoming.current;
753 if (!incoming.current->array) {
754 return NT_STATUS_NO_MEMORY;
757 incoming.previous = talloc(mem_ctx, struct AuthenticationInformationArray);
758 if (!incoming.previous) {
759 return NT_STATUS_NO_MEMORY;
761 incoming.previous->array = talloc_array(mem_ctx, struct AuthenticationInformation, incoming.count);
762 if (!incoming.previous->array) {
763 return NT_STATUS_NO_MEMORY;
766 for (i = 0; i < incoming.count; i++) {
767 incoming.previous->array[i].LastUpdateTime = 0;
768 incoming.previous->array[i].AuthType = 0;
770 ndr_err = ndr_push_struct_blob(&trustAuthIncoming, mem_ctx,
771 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
772 &incoming,
773 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
774 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
775 return NT_STATUS_INVALID_PARAMETER;
777 } else {
778 trustAuthIncoming = data_blob(NULL, 0);
781 if (auth_struct.outgoing.count) {
782 int i;
783 struct trustAuthInOutBlob outgoing;
785 outgoing.count = auth_struct.outgoing.count;
786 outgoing.current = talloc(mem_ctx, struct AuthenticationInformationArray);
787 if (!outgoing.current) {
788 return NT_STATUS_NO_MEMORY;
791 outgoing.current->array = *auth_struct.outgoing.current;
792 if (!outgoing.current->array) {
793 return NT_STATUS_NO_MEMORY;
796 outgoing.previous = talloc(mem_ctx, struct AuthenticationInformationArray);
797 if (!outgoing.previous) {
798 return NT_STATUS_NO_MEMORY;
800 outgoing.previous->array = talloc_array(mem_ctx, struct AuthenticationInformation, outgoing.count);
801 if (!outgoing.previous->array) {
802 return NT_STATUS_NO_MEMORY;
805 for (i = 0; i < outgoing.count; i++) {
806 outgoing.previous->array[i].LastUpdateTime = 0;
807 outgoing.previous->array[i].AuthType = 0;
809 ndr_err = ndr_push_struct_blob(&trustAuthOutgoing, mem_ctx,
810 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
811 &outgoing,
812 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
813 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
814 return NT_STATUS_INVALID_PARAMETER;
816 } else {
817 trustAuthOutgoing = data_blob(NULL, 0);
820 ret = ldb_transaction_start(policy_state->sam_ldb);
821 if (ret != LDB_SUCCESS) {
822 return NT_STATUS_INTERNAL_DB_CORRUPTION;
825 if (dns_name) {
826 char *dns_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
827 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
828 /* search for the trusted_domain record */
829 ret = gendb_search(policy_state->sam_ldb,
830 mem_ctx, policy_state->system_dn, &msgs, attrs,
831 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s)(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))",
832 dns_encoded, dns_encoded, dns_encoded, netbios_encoded, netbios_encoded, netbios_encoded);
833 if (ret > 0) {
834 ldb_transaction_cancel(policy_state->sam_ldb);
835 return NT_STATUS_OBJECT_NAME_COLLISION;
837 } else {
838 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
839 /* search for the trusted_domain record */
840 ret = gendb_search(policy_state->sam_ldb,
841 mem_ctx, policy_state->system_dn, &msgs, attrs,
842 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))",
843 netbios_encoded, netbios_encoded, netbios_encoded);
844 if (ret > 0) {
845 ldb_transaction_cancel(policy_state->sam_ldb);
846 return NT_STATUS_OBJECT_NAME_COLLISION;
850 if (ret < 0 ) {
851 ldb_transaction_cancel(policy_state->sam_ldb);
852 return NT_STATUS_INTERNAL_DB_CORRUPTION;
855 name = dns_name ? dns_name : netbios_name;
857 msg = ldb_msg_new(mem_ctx);
858 if (msg == NULL) {
859 return NT_STATUS_NO_MEMORY;
862 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
863 if ( ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name)) {
864 ldb_transaction_cancel(policy_state->sam_ldb);
865 return NT_STATUS_NO_MEMORY;
868 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "flatname", netbios_name);
870 if (r->in.info->sid) {
871 const char *sid_string = dom_sid_string(mem_ctx, r->in.info->sid);
872 if (!sid_string) {
873 ldb_transaction_cancel(policy_state->sam_ldb);
874 return NT_STATUS_NO_MEMORY;
877 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "securityIdentifier", sid_string);
880 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "objectClass", "trustedDomain");
882 samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustType", r->in.info->trust_type);
884 samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustAttributes", r->in.info->trust_attributes);
886 samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustDirection", r->in.info->trust_direction);
888 if (dns_name) {
889 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustPartner", dns_name);
892 if (trustAuthIncoming.data) {
893 ret = ldb_msg_add_value(msg, "trustAuthIncoming", &trustAuthIncoming, NULL);
894 if (ret != LDB_SUCCESS) {
895 ldb_transaction_cancel(policy_state->sam_ldb);
896 return NT_STATUS_NO_MEMORY;
899 if (trustAuthOutgoing.data) {
900 ret = ldb_msg_add_value(msg, "trustAuthOutgoing", &trustAuthOutgoing, NULL);
901 if (ret != LDB_SUCCESS) {
902 ldb_transaction_cancel(policy_state->sam_ldb);
903 return NT_STATUS_NO_MEMORY;
907 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
909 /* create the trusted_domain */
910 ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg);
911 switch (ret) {
912 case LDB_SUCCESS:
913 break;
914 case LDB_ERR_ENTRY_ALREADY_EXISTS:
915 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
916 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
917 ldb_dn_get_linearized(msg->dn),
918 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
919 return NT_STATUS_DOMAIN_EXISTS;
920 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
921 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
922 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
923 ldb_dn_get_linearized(msg->dn),
924 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
925 return NT_STATUS_ACCESS_DENIED;
926 default:
927 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
928 DEBUG(0,("Failed to create user record %s: %s\n",
929 ldb_dn_get_linearized(msg->dn),
930 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
931 return NT_STATUS_INTERNAL_DB_CORRUPTION;
934 if (r->in.info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
935 msg_user = ldb_msg_new(mem_ctx);
936 if (msg == NULL) {
937 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
938 return NT_STATUS_NO_MEMORY;
941 /* Inbound trusts must also create a cn=users object to match */
943 trusted_domain_state->trusted_domain_user_dn = msg_user->dn
944 = ldb_dn_copy(trusted_domain_state, policy_state->domain_dn);
945 if ( ! ldb_dn_add_child_fmt(msg_user->dn, "cn=users")) {
946 ldb_transaction_cancel(policy_state->sam_ldb);
947 return NT_STATUS_NO_MEMORY;
950 if ( ! ldb_dn_add_child_fmt(msg_user->dn, "cn=%s", netbios_name)) {
951 ldb_transaction_cancel(policy_state->sam_ldb);
952 return NT_STATUS_NO_MEMORY;
955 ldb_msg_add_string(msg_user, "objectClass", "user");
957 ldb_msg_add_steal_string(msg_user, "samAccountName",
958 talloc_asprintf(mem_ctx, "%s$", netbios_name));
960 if (samdb_msg_add_uint(trusted_domain_state->policy->sam_ldb, mem_ctx, msg_user,
961 "userAccountControl",
962 UF_INTERDOMAIN_TRUST_ACCOUNT) != 0) {
963 ldb_transaction_cancel(policy_state->sam_ldb);
964 return NT_STATUS_NO_MEMORY;
967 if (auth_struct.incoming.count) {
968 int i;
969 for (i=0; i < auth_struct.incoming.count; i++ ) {
970 if (auth_struct.incoming.current[i]->AuthType == TRUST_AUTH_TYPE_NT4OWF) {
971 samdb_msg_add_hash(trusted_domain_state->policy->sam_ldb,
972 mem_ctx, msg_user, "unicodePwd",
973 &auth_struct.incoming.current[i]->AuthInfo.nt4owf.password);
974 } else if (auth_struct.incoming.current[i]->AuthType == TRUST_AUTH_TYPE_CLEAR) {
975 DATA_BLOB new_password = data_blob_const(auth_struct.incoming.current[i]->AuthInfo.clear.password,
976 auth_struct.incoming.current[i]->AuthInfo.clear.size);
977 ret = ldb_msg_add_value(msg_user, "clearTextPassword", &new_password, NULL);
978 if (ret != LDB_SUCCESS) {
979 ldb_transaction_cancel(policy_state->sam_ldb);
980 return NT_STATUS_NO_MEMORY;
986 /* create the cn=users trusted_domain account */
987 ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg_user);
988 switch (ret) {
989 case LDB_SUCCESS:
990 break;
991 case LDB_ERR_ENTRY_ALREADY_EXISTS:
992 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
993 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
994 ldb_dn_get_linearized(msg_user->dn),
995 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
996 return NT_STATUS_DOMAIN_EXISTS;
997 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
998 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
999 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
1000 ldb_dn_get_linearized(msg_user->dn),
1001 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
1002 return NT_STATUS_ACCESS_DENIED;
1003 default:
1004 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
1005 DEBUG(0,("Failed to create user record %s: %s\n",
1006 ldb_dn_get_linearized(msg_user->dn),
1007 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
1008 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1012 ret = ldb_transaction_commit(policy_state->sam_ldb);
1013 if (ret != LDB_SUCCESS) {
1014 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1017 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1018 if (!handle) {
1019 return NT_STATUS_NO_MEMORY;
1022 handle->data = talloc_steal(handle, trusted_domain_state);
1024 trusted_domain_state->access_mask = r->in.access_mask;
1025 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1027 *r->out.trustdom_handle = handle->wire_handle;
1029 return NT_STATUS_OK;
1033 lsa_CreateTrustedDomainEx2
1035 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
1036 TALLOC_CTX *mem_ctx,
1037 struct lsa_CreateTrustedDomainEx2 *r)
1039 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, r, NDR_LSA_CREATETRUSTEDDOMAINEX2);
1042 lsa_CreateTrustedDomainEx
1044 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
1045 TALLOC_CTX *mem_ctx,
1046 struct lsa_CreateTrustedDomainEx *r)
1048 struct lsa_CreateTrustedDomainEx2 r2;
1050 r2.in.policy_handle = r->in.policy_handle;
1051 r2.in.info = r->in.info;
1052 r2.in.auth_info = r->in.auth_info;
1053 r2.out.trustdom_handle = r->out.trustdom_handle;
1054 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAINEX);
1058 lsa_CreateTrustedDomain
1060 static NTSTATUS dcesrv_lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1061 struct lsa_CreateTrustedDomain *r)
1063 struct lsa_CreateTrustedDomainEx2 r2;
1065 r2.in.policy_handle = r->in.policy_handle;
1066 r2.in.info = talloc(mem_ctx, struct lsa_TrustDomainInfoInfoEx);
1067 if (!r2.in.info) {
1068 return NT_STATUS_NO_MEMORY;
1071 r2.in.info->domain_name.string = NULL;
1072 r2.in.info->netbios_name = r->in.info->name;
1073 r2.in.info->sid = r->in.info->sid;
1074 r2.in.info->trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
1075 r2.in.info->trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1076 r2.in.info->trust_attributes = 0;
1078 r2.in.access_mask = r->in.access_mask;
1079 r2.out.trustdom_handle = r->out.trustdom_handle;
1081 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAIN);
1086 lsa_OpenTrustedDomain
1088 static NTSTATUS dcesrv_lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1089 struct lsa_OpenTrustedDomain *r)
1091 struct dcesrv_handle *policy_handle;
1093 struct lsa_policy_state *policy_state;
1094 struct lsa_trusted_domain_state *trusted_domain_state;
1095 struct dcesrv_handle *handle;
1096 struct ldb_message **msgs;
1097 const char *attrs[] = {
1098 "trustDirection",
1099 "flatname",
1100 NULL
1103 const char *sid_string;
1104 int ret;
1106 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1107 ZERO_STRUCTP(r->out.trustdom_handle);
1108 policy_state = policy_handle->data;
1110 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
1111 if (!trusted_domain_state) {
1112 return NT_STATUS_NO_MEMORY;
1114 trusted_domain_state->policy = policy_state;
1116 sid_string = dom_sid_string(mem_ctx, r->in.sid);
1117 if (!sid_string) {
1118 return NT_STATUS_NO_MEMORY;
1121 /* search for the trusted_domain record */
1122 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1123 mem_ctx, policy_state->system_dn, &msgs, attrs,
1124 "(&(securityIdentifier=%s)(objectclass=trustedDomain))",
1125 sid_string);
1126 if (ret == 0) {
1127 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1130 if (ret != 1) {
1131 DEBUG(0,("Found %d records matching DN %s\n", ret,
1132 ldb_dn_get_linearized(policy_state->system_dn)));
1133 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1136 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
1138 trusted_domain_state->trusted_domain_user_dn = NULL;
1140 if (ldb_msg_find_attr_as_int(msgs[0], "trustDirection", 0) & LSA_TRUST_DIRECTION_INBOUND) {
1141 const char *flatname = ldb_binary_encode_string(mem_ctx, ldb_msg_find_attr_as_string(msgs[0], "flatname", NULL));
1142 /* search for the trusted_domain record */
1143 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1144 mem_ctx, policy_state->domain_dn, &msgs, attrs,
1145 "(&(samaccountname=%s$)(objectclass=user)(userAccountControl:1.2.840.113556.1.4.803:=%d))",
1146 flatname, UF_INTERDOMAIN_TRUST_ACCOUNT);
1147 if (ret == 1) {
1148 trusted_domain_state->trusted_domain_user_dn = talloc_steal(trusted_domain_state, msgs[0]->dn);
1151 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1152 if (!handle) {
1153 return NT_STATUS_NO_MEMORY;
1156 handle->data = talloc_steal(handle, trusted_domain_state);
1158 trusted_domain_state->access_mask = r->in.access_mask;
1159 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1161 *r->out.trustdom_handle = handle->wire_handle;
1163 return NT_STATUS_OK;
1168 lsa_OpenTrustedDomainByName
1170 static NTSTATUS dcesrv_lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
1171 TALLOC_CTX *mem_ctx,
1172 struct lsa_OpenTrustedDomainByName *r)
1174 struct dcesrv_handle *policy_handle;
1176 struct lsa_policy_state *policy_state;
1177 struct lsa_trusted_domain_state *trusted_domain_state;
1178 struct dcesrv_handle *handle;
1179 struct ldb_message **msgs;
1180 const char *attrs[] = {
1181 NULL
1184 int ret;
1186 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1187 ZERO_STRUCTP(r->out.trustdom_handle);
1188 policy_state = policy_handle->data;
1190 if (!r->in.name.string) {
1191 return NT_STATUS_INVALID_PARAMETER;
1194 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
1195 if (!trusted_domain_state) {
1196 return NT_STATUS_NO_MEMORY;
1198 trusted_domain_state->policy = policy_state;
1200 /* search for the trusted_domain record */
1201 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1202 mem_ctx, policy_state->system_dn, &msgs, attrs,
1203 "(&(flatname=%s)(objectclass=trustedDomain))",
1204 ldb_binary_encode_string(mem_ctx, r->in.name.string));
1205 if (ret == 0) {
1206 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1209 if (ret != 1) {
1210 DEBUG(0,("Found %d records matching DN %s\n", ret,
1211 ldb_dn_get_linearized(policy_state->system_dn)));
1212 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1215 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
1217 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1218 if (!handle) {
1219 return NT_STATUS_NO_MEMORY;
1222 handle->data = talloc_steal(handle, trusted_domain_state);
1224 trusted_domain_state->access_mask = r->in.access_mask;
1225 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1227 *r->out.trustdom_handle = handle->wire_handle;
1229 return NT_STATUS_OK;
1235 lsa_SetTrustedDomainInfo
1237 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1238 struct lsa_SetTrustedDomainInfo *r)
1240 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1246 lsa_SetInfomrationTrustedDomain
1248 static NTSTATUS dcesrv_lsa_SetInformationTrustedDomain(struct dcesrv_call_state *dce_call,
1249 TALLOC_CTX *mem_ctx,
1250 struct lsa_SetInformationTrustedDomain *r)
1252 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1257 lsa_DeleteTrustedDomain
1259 static NTSTATUS dcesrv_lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1260 struct lsa_DeleteTrustedDomain *r)
1262 NTSTATUS status;
1263 struct lsa_OpenTrustedDomain open;
1264 struct lsa_DeleteObject delete;
1265 struct dcesrv_handle *h;
1267 open.in.handle = r->in.handle;
1268 open.in.sid = r->in.dom_sid;
1269 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1270 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1271 if (!open.out.trustdom_handle) {
1272 return NT_STATUS_NO_MEMORY;
1274 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
1275 if (!NT_STATUS_IS_OK(status)) {
1276 return status;
1279 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1280 talloc_steal(mem_ctx, h);
1282 delete.in.handle = open.out.trustdom_handle;
1283 delete.out.handle = open.out.trustdom_handle;
1284 status = dcesrv_lsa_DeleteObject(dce_call, mem_ctx, &delete);
1285 if (!NT_STATUS_IS_OK(status)) {
1286 return status;
1288 return NT_STATUS_OK;
1291 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx,
1292 struct ldb_message *msg,
1293 struct lsa_TrustDomainInfoInfoEx *info_ex)
1295 info_ex->domain_name.string
1296 = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
1297 info_ex->netbios_name.string
1298 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1299 info_ex->sid
1300 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1301 info_ex->trust_direction
1302 = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
1303 info_ex->trust_type
1304 = ldb_msg_find_attr_as_int(msg, "trustType", 0);
1305 info_ex->trust_attributes
1306 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);
1307 return NT_STATUS_OK;
1311 lsa_QueryTrustedDomainInfo
1313 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1314 struct lsa_QueryTrustedDomainInfo *r)
1316 union lsa_TrustedDomainInfo *info = NULL;
1317 struct dcesrv_handle *h;
1318 struct lsa_trusted_domain_state *trusted_domain_state;
1319 struct ldb_message *msg;
1320 int ret;
1321 struct ldb_message **res;
1322 const char *attrs[] = {
1323 "flatname",
1324 "trustPartner",
1325 "securityIdentifier",
1326 "trustDirection",
1327 "trustType",
1328 "trustAttributes",
1329 "msDs-supportedEncryptionTypes",
1330 NULL
1333 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
1335 trusted_domain_state = talloc_get_type(h->data, struct lsa_trusted_domain_state);
1337 /* pull all the user attributes */
1338 ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
1339 trusted_domain_state->trusted_domain_dn, &res, attrs);
1340 if (ret != 1) {
1341 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1343 msg = res[0];
1345 info = talloc_zero(mem_ctx, union lsa_TrustedDomainInfo);
1346 if (!info) {
1347 return NT_STATUS_NO_MEMORY;
1349 *r->out.info = info;
1351 switch (r->in.level) {
1352 case LSA_TRUSTED_DOMAIN_INFO_NAME:
1353 info->name.netbios_name.string
1354 = samdb_result_string(msg, "flatname", NULL);
1355 break;
1356 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1357 info->posix_offset.posix_offset
1358 = samdb_result_uint(msg, "posixOffset", 0);
1359 break;
1360 #if 0 /* Win2k3 doesn't implement this */
1361 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
1362 r->out.info->info_basic.netbios_name.string
1363 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1364 r->out.info->info_basic.sid
1365 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1366 break;
1367 #endif
1368 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1369 return fill_trust_domain_ex(mem_ctx, msg, &info->info_ex);
1371 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1372 ZERO_STRUCT(info->full_info);
1373 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info.info_ex);
1375 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
1376 ZERO_STRUCT(info->full_info2_internal);
1377 info->full_info2_internal.posix_offset.posix_offset
1378 = samdb_result_uint(msg, "posixOffset", 0);
1379 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info2_internal.info.info_ex);
1381 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES:
1382 info->enc_types.enc_types
1383 = samdb_result_uint(msg, "msDs-supportedEncryptionTypes", KERB_ENCTYPE_RC4_HMAC_MD5);
1384 break;
1386 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
1387 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
1388 /* oops, we don't want to return the info after all */
1389 talloc_free(info);
1390 *r->out.info = NULL;
1391 return NT_STATUS_INVALID_PARAMETER;
1392 default:
1393 /* oops, we don't want to return the info after all */
1394 talloc_free(info);
1395 *r->out.info = NULL;
1396 return NT_STATUS_INVALID_INFO_CLASS;
1399 return NT_STATUS_OK;
1404 lsa_QueryTrustedDomainInfoBySid
1406 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1407 struct lsa_QueryTrustedDomainInfoBySid *r)
1409 NTSTATUS status;
1410 struct lsa_OpenTrustedDomain open;
1411 struct lsa_QueryTrustedDomainInfo query;
1412 struct dcesrv_handle *h;
1413 open.in.handle = r->in.handle;
1414 open.in.sid = r->in.dom_sid;
1415 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1416 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1417 if (!open.out.trustdom_handle) {
1418 return NT_STATUS_NO_MEMORY;
1420 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
1421 if (!NT_STATUS_IS_OK(status)) {
1422 return status;
1425 /* Ensure this handle goes away at the end of this call */
1426 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1427 talloc_steal(mem_ctx, h);
1429 query.in.trustdom_handle = open.out.trustdom_handle;
1430 query.in.level = r->in.level;
1431 query.out.info = r->out.info;
1432 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1433 if (!NT_STATUS_IS_OK(status)) {
1434 return status;
1437 return NT_STATUS_OK;
1441 lsa_SetTrustedDomainInfoByName
1443 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1444 TALLOC_CTX *mem_ctx,
1445 struct lsa_SetTrustedDomainInfoByName *r)
1447 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1451 lsa_QueryTrustedDomainInfoByName
1453 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1454 TALLOC_CTX *mem_ctx,
1455 struct lsa_QueryTrustedDomainInfoByName *r)
1457 NTSTATUS status;
1458 struct lsa_OpenTrustedDomainByName open;
1459 struct lsa_QueryTrustedDomainInfo query;
1460 struct dcesrv_handle *h;
1461 open.in.handle = r->in.handle;
1462 open.in.name = *r->in.trusted_domain;
1463 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1464 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1465 if (!open.out.trustdom_handle) {
1466 return NT_STATUS_NO_MEMORY;
1468 status = dcesrv_lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &open);
1469 if (!NT_STATUS_IS_OK(status)) {
1470 return status;
1473 /* Ensure this handle goes away at the end of this call */
1474 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1475 talloc_steal(mem_ctx, h);
1477 query.in.trustdom_handle = open.out.trustdom_handle;
1478 query.in.level = r->in.level;
1479 query.out.info = r->out.info;
1480 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1481 if (!NT_STATUS_IS_OK(status)) {
1482 return status;
1485 return NT_STATUS_OK;
1489 lsa_CloseTrustedDomainEx
1491 static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
1492 TALLOC_CTX *mem_ctx,
1493 struct lsa_CloseTrustedDomainEx *r)
1495 /* The result of a bad hair day from an IDL programmer? Not
1496 * implmented in Win2k3. You should always just lsa_Close
1497 * anyway. */
1498 return NT_STATUS_NOT_IMPLEMENTED;
1503 comparison function for sorting lsa_DomainInformation array
1505 static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
1507 return strcasecmp_m(e1->name.string, e2->name.string);
1511 lsa_EnumTrustDom
1513 static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1514 struct lsa_EnumTrustDom *r)
1516 struct dcesrv_handle *policy_handle;
1517 struct lsa_DomainInfo *entries;
1518 struct lsa_policy_state *policy_state;
1519 struct ldb_message **domains;
1520 const char *attrs[] = {
1521 "flatname",
1522 "securityIdentifier",
1523 NULL
1527 int count, i;
1529 *r->out.resume_handle = 0;
1531 r->out.domains->domains = NULL;
1532 r->out.domains->count = 0;
1534 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1536 policy_state = policy_handle->data;
1538 /* search for all users in this domain. This could possibly be cached and
1539 resumed based on resume_key */
1540 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1541 "objectclass=trustedDomain");
1542 if (count == -1) {
1543 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1546 /* convert to lsa_TrustInformation format */
1547 entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
1548 if (!entries) {
1549 return NT_STATUS_NO_MEMORY;
1551 for (i=0;i<count;i++) {
1552 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
1553 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
1556 /* sort the results by name */
1557 qsort(entries, count, sizeof(*entries),
1558 (comparison_fn_t)compare_DomainInfo);
1560 if (*r->in.resume_handle >= count) {
1561 *r->out.resume_handle = -1;
1563 return NT_STATUS_NO_MORE_ENTRIES;
1566 /* return the rest, limit by max_size. Note that we
1567 use the w2k3 element size value of 60 */
1568 r->out.domains->count = count - *r->in.resume_handle;
1569 r->out.domains->count = MIN(r->out.domains->count,
1570 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
1572 r->out.domains->domains = entries + *r->in.resume_handle;
1573 r->out.domains->count = r->out.domains->count;
1575 if (r->out.domains->count < count - *r->in.resume_handle) {
1576 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1577 return STATUS_MORE_ENTRIES;
1580 return NT_STATUS_OK;
1584 comparison function for sorting lsa_DomainInformation array
1586 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
1588 return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
1592 lsa_EnumTrustedDomainsEx
1594 static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1595 struct lsa_EnumTrustedDomainsEx *r)
1597 struct dcesrv_handle *policy_handle;
1598 struct lsa_TrustDomainInfoInfoEx *entries;
1599 struct lsa_policy_state *policy_state;
1600 struct ldb_message **domains;
1601 const char *attrs[] = {
1602 "flatname",
1603 "trustPartner",
1604 "securityIdentifier",
1605 "trustDirection",
1606 "trustType",
1607 "trustAttributes",
1608 NULL
1610 NTSTATUS nt_status;
1612 int count, i;
1614 *r->out.resume_handle = 0;
1616 r->out.domains->domains = NULL;
1617 r->out.domains->count = 0;
1619 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1621 policy_state = policy_handle->data;
1623 /* search for all users in this domain. This could possibly be cached and
1624 resumed based on resume_key */
1625 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1626 "objectclass=trustedDomain");
1627 if (count == -1) {
1628 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1631 /* convert to lsa_DomainInformation format */
1632 entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
1633 if (!entries) {
1634 return NT_STATUS_NO_MEMORY;
1636 for (i=0;i<count;i++) {
1637 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
1638 if (!NT_STATUS_IS_OK(nt_status)) {
1639 return nt_status;
1643 /* sort the results by name */
1644 qsort(entries, count, sizeof(*entries),
1645 (comparison_fn_t)compare_TrustDomainInfoInfoEx);
1647 if (*r->in.resume_handle >= count) {
1648 *r->out.resume_handle = -1;
1650 return NT_STATUS_NO_MORE_ENTRIES;
1653 /* return the rest, limit by max_size. Note that we
1654 use the w2k3 element size value of 60 */
1655 r->out.domains->count = count - *r->in.resume_handle;
1656 r->out.domains->count = MIN(r->out.domains->count,
1657 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
1659 r->out.domains->domains = entries + *r->in.resume_handle;
1660 r->out.domains->count = r->out.domains->count;
1662 if (r->out.domains->count < count - *r->in.resume_handle) {
1663 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1664 return STATUS_MORE_ENTRIES;
1667 return NT_STATUS_OK;
1672 lsa_OpenAccount
1674 static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1675 struct lsa_OpenAccount *r)
1677 struct dcesrv_handle *h, *ah;
1678 struct lsa_policy_state *state;
1679 struct lsa_account_state *astate;
1681 ZERO_STRUCTP(r->out.acct_handle);
1683 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1685 state = h->data;
1687 astate = talloc(dce_call->conn, struct lsa_account_state);
1688 if (astate == NULL) {
1689 return NT_STATUS_NO_MEMORY;
1692 astate->account_sid = dom_sid_dup(astate, r->in.sid);
1693 if (astate->account_sid == NULL) {
1694 talloc_free(astate);
1695 return NT_STATUS_NO_MEMORY;
1698 astate->policy = talloc_reference(astate, state);
1699 astate->access_mask = r->in.access_mask;
1701 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
1702 if (!ah) {
1703 talloc_free(astate);
1704 return NT_STATUS_NO_MEMORY;
1707 ah->data = talloc_steal(ah, astate);
1709 *r->out.acct_handle = ah->wire_handle;
1711 return NT_STATUS_OK;
1716 lsa_EnumPrivsAccount
1718 static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
1719 TALLOC_CTX *mem_ctx,
1720 struct lsa_EnumPrivsAccount *r)
1722 struct dcesrv_handle *h;
1723 struct lsa_account_state *astate;
1724 int ret, i;
1725 struct ldb_message **res;
1726 const char * const attrs[] = { "privilege", NULL};
1727 struct ldb_message_element *el;
1728 const char *sidstr;
1729 struct lsa_PrivilegeSet *privs;
1731 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1733 astate = h->data;
1735 privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
1736 if (privs == NULL) {
1737 return NT_STATUS_NO_MEMORY;
1739 privs->count = 0;
1740 privs->unknown = 0;
1741 privs->set = NULL;
1743 *r->out.privs = privs;
1745 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
1746 if (sidstr == NULL) {
1747 return NT_STATUS_NO_MEMORY;
1750 ret = gendb_search(astate->policy->sam_ldb, mem_ctx, NULL, &res, attrs,
1751 "objectSid=%s", sidstr);
1752 if (ret != 1) {
1753 return NT_STATUS_OK;
1756 el = ldb_msg_find_element(res[0], "privilege");
1757 if (el == NULL || el->num_values == 0) {
1758 return NT_STATUS_OK;
1761 privs->set = talloc_array(privs,
1762 struct lsa_LUIDAttribute, el->num_values);
1763 if (privs->set == NULL) {
1764 return NT_STATUS_NO_MEMORY;
1767 for (i=0;i<el->num_values;i++) {
1768 int id = sec_privilege_id((const char *)el->values[i].data);
1769 if (id == -1) {
1770 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1772 privs->set[i].attribute = 0;
1773 privs->set[i].luid.low = id;
1774 privs->set[i].luid.high = 0;
1777 privs->count = el->num_values;
1779 return NT_STATUS_OK;
1783 lsa_EnumAccountRights
1785 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
1786 TALLOC_CTX *mem_ctx,
1787 struct lsa_EnumAccountRights *r)
1789 struct dcesrv_handle *h;
1790 struct lsa_policy_state *state;
1791 int ret, i;
1792 struct ldb_message **res;
1793 const char * const attrs[] = { "privilege", NULL};
1794 const char *sidstr;
1795 struct ldb_message_element *el;
1797 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1799 state = h->data;
1801 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
1802 if (sidstr == NULL) {
1803 return NT_STATUS_NO_MEMORY;
1806 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
1807 "(&(objectSid=%s)(privilege=*))", sidstr);
1808 if (ret == 0) {
1809 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1811 if (ret > 1) {
1812 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1814 if (ret == -1) {
1815 DEBUG(3, ("searching for account rights for SID: %s failed: %s",
1816 dom_sid_string(mem_ctx, r->in.sid),
1817 ldb_errstring(state->sam_ldb)));
1818 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1821 el = ldb_msg_find_element(res[0], "privilege");
1822 if (el == NULL || el->num_values == 0) {
1823 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1826 r->out.rights->count = el->num_values;
1827 r->out.rights->names = talloc_array(r->out.rights,
1828 struct lsa_StringLarge, r->out.rights->count);
1829 if (r->out.rights->names == NULL) {
1830 return NT_STATUS_NO_MEMORY;
1833 for (i=0;i<el->num_values;i++) {
1834 r->out.rights->names[i].string = (const char *)el->values[i].data;
1837 return NT_STATUS_OK;
1843 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
1845 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
1846 TALLOC_CTX *mem_ctx,
1847 struct lsa_policy_state *state,
1848 int ldb_flag,
1849 struct dom_sid *sid,
1850 const struct lsa_RightSet *rights)
1852 const char *sidstr;
1853 struct ldb_message *msg;
1854 struct ldb_message_element *el;
1855 int i, ret;
1856 struct lsa_EnumAccountRights r2;
1858 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, sid);
1859 if (sidstr == NULL) {
1860 return NT_STATUS_NO_MEMORY;
1863 msg = ldb_msg_new(mem_ctx);
1864 if (msg == NULL) {
1865 return NT_STATUS_NO_MEMORY;
1868 msg->dn = samdb_search_dn(state->sam_ldb, mem_ctx,
1869 NULL, "objectSid=%s", sidstr);
1870 if (msg->dn == NULL) {
1871 NTSTATUS status;
1872 if (ldb_flag == LDB_FLAG_MOD_DELETE) {
1873 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1875 status = samdb_create_foreign_security_principal(state->sam_ldb, mem_ctx,
1876 sid, &msg->dn);
1877 if (!NT_STATUS_IS_OK(status)) {
1878 return status;
1880 return NT_STATUS_NO_SUCH_USER;
1883 if (ldb_msg_add_empty(msg, "privilege", ldb_flag, NULL)) {
1884 return NT_STATUS_NO_MEMORY;
1887 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1888 NTSTATUS status;
1890 r2.in.handle = &state->handle->wire_handle;
1891 r2.in.sid = sid;
1892 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
1894 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1895 if (!NT_STATUS_IS_OK(status)) {
1896 ZERO_STRUCTP(r2.out.rights);
1900 for (i=0;i<rights->count;i++) {
1901 if (sec_privilege_id(rights->names[i].string) == -1) {
1902 return NT_STATUS_NO_SUCH_PRIVILEGE;
1905 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1906 int j;
1907 for (j=0;j<r2.out.rights->count;j++) {
1908 if (strcasecmp_m(r2.out.rights->names[j].string,
1909 rights->names[i].string) == 0) {
1910 break;
1913 if (j != r2.out.rights->count) continue;
1916 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
1917 if (ret != LDB_SUCCESS) {
1918 return NT_STATUS_NO_MEMORY;
1922 el = ldb_msg_find_element(msg, "privilege");
1923 if (!el) {
1924 return NT_STATUS_OK;
1927 ret = ldb_modify(state->sam_ldb, msg);
1928 if (ret != 0) {
1929 if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1930 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1932 DEBUG(3, ("Could not %s attributes from %s: %s",
1933 ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add",
1934 ldb_dn_get_linearized(msg->dn), ldb_errstring(state->sam_ldb)));
1935 return NT_STATUS_UNEXPECTED_IO_ERROR;
1938 return NT_STATUS_OK;
1942 lsa_AddPrivilegesToAccount
1944 static NTSTATUS dcesrv_lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1945 struct lsa_AddPrivilegesToAccount *r)
1947 struct lsa_RightSet rights;
1948 struct dcesrv_handle *h;
1949 struct lsa_account_state *astate;
1950 int i;
1952 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1954 astate = h->data;
1956 rights.count = r->in.privs->count;
1957 rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
1958 if (rights.names == NULL) {
1959 return NT_STATUS_NO_MEMORY;
1961 for (i=0;i<rights.count;i++) {
1962 int id = r->in.privs->set[i].luid.low;
1963 if (r->in.privs->set[i].luid.high) {
1964 return NT_STATUS_NO_SUCH_PRIVILEGE;
1966 rights.names[i].string = sec_privilege_name(id);
1967 if (rights.names[i].string == NULL) {
1968 return NT_STATUS_NO_SUCH_PRIVILEGE;
1972 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1973 LDB_FLAG_MOD_ADD, astate->account_sid,
1974 &rights);
1979 lsa_RemovePrivilegesFromAccount
1981 static NTSTATUS dcesrv_lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1982 struct lsa_RemovePrivilegesFromAccount *r)
1984 struct lsa_RightSet *rights;
1985 struct dcesrv_handle *h;
1986 struct lsa_account_state *astate;
1987 int i;
1989 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1991 astate = h->data;
1993 rights = talloc(mem_ctx, struct lsa_RightSet);
1995 if (r->in.remove_all == 1 &&
1996 r->in.privs == NULL) {
1997 struct lsa_EnumAccountRights r2;
1998 NTSTATUS status;
2000 r2.in.handle = &astate->policy->handle->wire_handle;
2001 r2.in.sid = astate->account_sid;
2002 r2.out.rights = rights;
2004 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
2005 if (!NT_STATUS_IS_OK(status)) {
2006 return status;
2009 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2010 LDB_FLAG_MOD_DELETE, astate->account_sid,
2011 r2.out.rights);
2014 if (r->in.remove_all != 0) {
2015 return NT_STATUS_INVALID_PARAMETER;
2018 rights->count = r->in.privs->count;
2019 rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
2020 if (rights->names == NULL) {
2021 return NT_STATUS_NO_MEMORY;
2023 for (i=0;i<rights->count;i++) {
2024 int id = r->in.privs->set[i].luid.low;
2025 if (r->in.privs->set[i].luid.high) {
2026 return NT_STATUS_NO_SUCH_PRIVILEGE;
2028 rights->names[i].string = sec_privilege_name(id);
2029 if (rights->names[i].string == NULL) {
2030 return NT_STATUS_NO_SUCH_PRIVILEGE;
2034 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2035 LDB_FLAG_MOD_DELETE, astate->account_sid,
2036 rights);
2041 lsa_GetQuotasForAccount
2043 static NTSTATUS dcesrv_lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2044 struct lsa_GetQuotasForAccount *r)
2046 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2051 lsa_SetQuotasForAccount
2053 static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2054 struct lsa_SetQuotasForAccount *r)
2056 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2061 lsa_GetSystemAccessAccount
2063 static NTSTATUS dcesrv_lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2064 struct lsa_GetSystemAccessAccount *r)
2066 int i;
2067 NTSTATUS status;
2068 struct lsa_EnumPrivsAccount enumPrivs;
2069 struct lsa_PrivilegeSet *privs;
2071 privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
2072 if (!privs) {
2073 return NT_STATUS_NO_MEMORY;
2075 privs->count = 0;
2076 privs->unknown = 0;
2077 privs->set = NULL;
2079 enumPrivs.in.handle = r->in.handle;
2080 enumPrivs.out.privs = &privs;
2082 status = dcesrv_lsa_EnumPrivsAccount(dce_call, mem_ctx, &enumPrivs);
2083 if (!NT_STATUS_IS_OK(status)) {
2084 return status;
2087 *(r->out.access_mask) = 0x00000000;
2089 for (i = 0; i < privs->count; i++) {
2090 int priv = privs->set[i].luid.low;
2092 switch (priv) {
2093 case SEC_PRIV_INTERACTIVE_LOGON:
2094 *(r->out.access_mask) |= LSA_POLICY_MODE_INTERACTIVE;
2095 break;
2096 case SEC_PRIV_NETWORK_LOGON:
2097 *(r->out.access_mask) |= LSA_POLICY_MODE_NETWORK;
2098 break;
2099 case SEC_PRIV_REMOTE_INTERACTIVE_LOGON:
2100 *(r->out.access_mask) |= LSA_POLICY_MODE_REMOTE_INTERACTIVE;
2101 break;
2105 return NT_STATUS_OK;
2110 lsa_SetSystemAccessAccount
2112 static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2113 struct lsa_SetSystemAccessAccount *r)
2115 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2120 lsa_CreateSecret
2122 static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2123 struct lsa_CreateSecret *r)
2125 struct dcesrv_handle *policy_handle;
2126 struct lsa_policy_state *policy_state;
2127 struct lsa_secret_state *secret_state;
2128 struct dcesrv_handle *handle;
2129 struct ldb_message **msgs, *msg;
2130 const char *errstr;
2131 const char *attrs[] = {
2132 NULL
2135 const char *name;
2137 int ret;
2139 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2140 ZERO_STRUCTP(r->out.sec_handle);
2142 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2144 case SECURITY_SYSTEM:
2145 case SECURITY_ADMINISTRATOR:
2146 break;
2147 default:
2148 /* Users and annonymous are not allowed create secrets */
2149 return NT_STATUS_ACCESS_DENIED;
2152 policy_state = policy_handle->data;
2154 if (!r->in.name.string) {
2155 return NT_STATUS_INVALID_PARAMETER;
2158 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2159 if (!secret_state) {
2160 return NT_STATUS_NO_MEMORY;
2162 secret_state->policy = policy_state;
2164 msg = ldb_msg_new(mem_ctx);
2165 if (msg == NULL) {
2166 return NT_STATUS_NO_MEMORY;
2169 if (strncmp("G$", r->in.name.string, 2) == 0) {
2170 const char *name2;
2171 name = &r->in.name.string[2];
2172 /* 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) */
2173 secret_state->sam_ldb = talloc_reference(secret_state,
2174 samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(secret_state, dce_call->conn->dce_ctx->lp_ctx)));
2175 secret_state->global = true;
2177 if (strlen(name) < 1) {
2178 return NT_STATUS_INVALID_PARAMETER;
2181 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
2182 /* search for the secret record */
2183 ret = gendb_search(secret_state->sam_ldb,
2184 mem_ctx, policy_state->system_dn, &msgs, attrs,
2185 "(&(cn=%s)(objectclass=secret))",
2186 name2);
2187 if (ret > 0) {
2188 return NT_STATUS_OBJECT_NAME_COLLISION;
2191 if (ret == -1) {
2192 DEBUG(0,("Failure searching for CN=%s: %s\n",
2193 name2, ldb_errstring(secret_state->sam_ldb)));
2194 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2197 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
2198 if (!name2 || ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
2199 return NT_STATUS_NO_MEMORY;
2202 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
2204 } else {
2205 secret_state->global = false;
2207 name = r->in.name.string;
2208 if (strlen(name) < 1) {
2209 return NT_STATUS_INVALID_PARAMETER;
2212 secret_state->sam_ldb = talloc_reference(secret_state,
2213 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
2214 /* search for the secret record */
2215 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2216 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2217 &msgs, attrs,
2218 "(&(cn=%s)(objectclass=secret))",
2219 ldb_binary_encode_string(mem_ctx, name));
2220 if (ret > 0) {
2221 return NT_STATUS_OBJECT_NAME_COLLISION;
2224 if (ret == -1) {
2225 DEBUG(0,("Failure searching for CN=%s: %s\n",
2226 name, ldb_errstring(secret_state->sam_ldb)));
2227 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2230 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name);
2231 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
2234 /* pull in all the template attributes. Note this is always from the global samdb */
2235 ret = samdb_copy_template(secret_state->policy->sam_ldb, msg,
2236 "secret", &errstr);
2237 if (ret != 0) {
2238 DEBUG(0,("Failed to load TemplateSecret from samdb: %s\n",
2239 errstr));
2240 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2243 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
2245 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
2247 /* create the secret */
2248 ret = ldb_add(secret_state->sam_ldb, msg);
2249 if (ret != 0) {
2250 DEBUG(0,("Failed to create secret record %s: %s\n",
2251 ldb_dn_get_linearized(msg->dn),
2252 ldb_errstring(secret_state->sam_ldb)));
2253 return NT_STATUS_ACCESS_DENIED;
2256 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2257 if (!handle) {
2258 return NT_STATUS_NO_MEMORY;
2261 handle->data = talloc_steal(handle, secret_state);
2263 secret_state->access_mask = r->in.access_mask;
2264 secret_state->policy = talloc_reference(secret_state, policy_state);
2266 *r->out.sec_handle = handle->wire_handle;
2268 return NT_STATUS_OK;
2273 lsa_OpenSecret
2275 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2276 struct lsa_OpenSecret *r)
2278 struct dcesrv_handle *policy_handle;
2280 struct lsa_policy_state *policy_state;
2281 struct lsa_secret_state *secret_state;
2282 struct dcesrv_handle *handle;
2283 struct ldb_message **msgs;
2284 const char *attrs[] = {
2285 NULL
2288 const char *name;
2290 int ret;
2292 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2293 ZERO_STRUCTP(r->out.sec_handle);
2294 policy_state = policy_handle->data;
2296 if (!r->in.name.string) {
2297 return NT_STATUS_INVALID_PARAMETER;
2300 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2302 case SECURITY_SYSTEM:
2303 case SECURITY_ADMINISTRATOR:
2304 break;
2305 default:
2306 /* Users and annonymous are not allowed to access secrets */
2307 return NT_STATUS_ACCESS_DENIED;
2310 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2311 if (!secret_state) {
2312 return NT_STATUS_NO_MEMORY;
2314 secret_state->policy = policy_state;
2316 if (strncmp("G$", r->in.name.string, 2) == 0) {
2317 name = &r->in.name.string[2];
2318 /* 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) */
2319 secret_state->sam_ldb = talloc_reference(secret_state,
2320 samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(secret_state, dce_call->conn->dce_ctx->lp_ctx)));
2321 secret_state->global = true;
2323 if (strlen(name) < 1) {
2324 return NT_STATUS_INVALID_PARAMETER;
2327 /* search for the secret record */
2328 ret = gendb_search(secret_state->sam_ldb,
2329 mem_ctx, policy_state->system_dn, &msgs, attrs,
2330 "(&(cn=%s Secret)(objectclass=secret))",
2331 ldb_binary_encode_string(mem_ctx, name));
2332 if (ret == 0) {
2333 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2336 if (ret != 1) {
2337 DEBUG(0,("Found %d records matching DN %s\n", ret,
2338 ldb_dn_get_linearized(policy_state->system_dn)));
2339 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2342 } else {
2343 secret_state->global = false;
2344 secret_state->sam_ldb = talloc_reference(secret_state,
2345 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
2347 name = r->in.name.string;
2348 if (strlen(name) < 1) {
2349 return NT_STATUS_INVALID_PARAMETER;
2352 /* search for the secret record */
2353 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2354 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2355 &msgs, attrs,
2356 "(&(cn=%s)(objectclass=secret))",
2357 ldb_binary_encode_string(mem_ctx, name));
2358 if (ret == 0) {
2359 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2362 if (ret != 1) {
2363 DEBUG(0,("Found %d records matching CN=%s\n",
2364 ret, ldb_binary_encode_string(mem_ctx, name)));
2365 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2369 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
2371 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2372 if (!handle) {
2373 return NT_STATUS_NO_MEMORY;
2376 handle->data = talloc_steal(handle, secret_state);
2378 secret_state->access_mask = r->in.access_mask;
2379 secret_state->policy = talloc_reference(secret_state, policy_state);
2381 *r->out.sec_handle = handle->wire_handle;
2383 return NT_STATUS_OK;
2388 lsa_SetSecret
2390 static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2391 struct lsa_SetSecret *r)
2394 struct dcesrv_handle *h;
2395 struct lsa_secret_state *secret_state;
2396 struct ldb_message *msg;
2397 DATA_BLOB session_key;
2398 DATA_BLOB crypt_secret, secret;
2399 struct ldb_val val;
2400 int ret;
2401 NTSTATUS status = NT_STATUS_OK;
2403 struct timeval now = timeval_current();
2404 NTTIME nt_now = timeval_to_nttime(&now);
2406 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2408 secret_state = h->data;
2410 msg = ldb_msg_new(mem_ctx);
2411 if (msg == NULL) {
2412 return NT_STATUS_NO_MEMORY;
2415 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
2416 if (!msg->dn) {
2417 return NT_STATUS_NO_MEMORY;
2419 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2420 if (!NT_STATUS_IS_OK(status)) {
2421 return status;
2424 if (r->in.old_val) {
2425 /* Decrypt */
2426 crypt_secret.data = r->in.old_val->data;
2427 crypt_secret.length = r->in.old_val->size;
2429 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2430 if (!NT_STATUS_IS_OK(status)) {
2431 return status;
2434 val.data = secret.data;
2435 val.length = secret.length;
2437 /* set value */
2438 if (samdb_msg_add_value(secret_state->sam_ldb,
2439 mem_ctx, msg, "priorValue", &val) != 0) {
2440 return NT_STATUS_NO_MEMORY;
2443 /* set old value mtime */
2444 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2445 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
2446 return NT_STATUS_NO_MEMORY;
2449 } else {
2450 /* If the old value is not set, then migrate the
2451 * current value to the old value */
2452 const struct ldb_val *old_val;
2453 NTTIME last_set_time;
2454 struct ldb_message **res;
2455 const char *attrs[] = {
2456 "currentValue",
2457 "lastSetTime",
2458 NULL
2461 /* search for the secret record */
2462 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
2463 secret_state->secret_dn, &res, attrs);
2464 if (ret == 0) {
2465 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2468 if (ret != 1) {
2469 DEBUG(0,("Found %d records matching dn=%s\n", ret,
2470 ldb_dn_get_linearized(secret_state->secret_dn)));
2471 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2474 old_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2475 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2477 if (old_val) {
2478 /* set old value */
2479 if (samdb_msg_add_value(secret_state->sam_ldb,
2480 mem_ctx, msg, "priorValue",
2481 old_val) != 0) {
2482 return NT_STATUS_NO_MEMORY;
2484 } else {
2485 if (samdb_msg_add_delete(secret_state->sam_ldb,
2486 mem_ctx, msg, "priorValue")) {
2487 return NT_STATUS_NO_MEMORY;
2492 /* set old value mtime */
2493 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2494 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2495 mem_ctx, msg, "priorSetTime", last_set_time) != 0) {
2496 return NT_STATUS_NO_MEMORY;
2498 } else {
2499 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2500 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
2501 return NT_STATUS_NO_MEMORY;
2506 if (r->in.new_val) {
2507 /* Decrypt */
2508 crypt_secret.data = r->in.new_val->data;
2509 crypt_secret.length = r->in.new_val->size;
2511 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2512 if (!NT_STATUS_IS_OK(status)) {
2513 return status;
2516 val.data = secret.data;
2517 val.length = secret.length;
2519 /* set value */
2520 if (samdb_msg_add_value(secret_state->sam_ldb,
2521 mem_ctx, msg, "currentValue", &val) != 0) {
2522 return NT_STATUS_NO_MEMORY;
2525 /* set new value mtime */
2526 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2527 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2528 return NT_STATUS_NO_MEMORY;
2531 } else {
2532 /* NULL out the NEW value */
2533 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2534 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2535 return NT_STATUS_NO_MEMORY;
2537 if (samdb_msg_add_delete(secret_state->sam_ldb,
2538 mem_ctx, msg, "currentValue")) {
2539 return NT_STATUS_NO_MEMORY;
2543 /* modify the samdb record */
2544 ret = samdb_replace(secret_state->sam_ldb, mem_ctx, msg);
2545 if (ret != 0) {
2546 /* we really need samdb.c to return NTSTATUS */
2547 return NT_STATUS_UNSUCCESSFUL;
2550 return NT_STATUS_OK;
2555 lsa_QuerySecret
2557 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2558 struct lsa_QuerySecret *r)
2560 struct dcesrv_handle *h;
2561 struct lsa_secret_state *secret_state;
2562 struct ldb_message *msg;
2563 DATA_BLOB session_key;
2564 DATA_BLOB crypt_secret, secret;
2565 int ret;
2566 struct ldb_message **res;
2567 const char *attrs[] = {
2568 "currentValue",
2569 "priorValue",
2570 "lastSetTime",
2571 "priorSetTime",
2572 NULL
2575 NTSTATUS nt_status;
2577 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2579 /* Ensure user is permitted to read this... */
2580 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2582 case SECURITY_SYSTEM:
2583 case SECURITY_ADMINISTRATOR:
2584 break;
2585 default:
2586 /* Users and annonymous are not allowed to read secrets */
2587 return NT_STATUS_ACCESS_DENIED;
2590 secret_state = h->data;
2592 /* pull all the user attributes */
2593 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2594 secret_state->secret_dn, &res, attrs);
2595 if (ret != 1) {
2596 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2598 msg = res[0];
2600 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2601 if (!NT_STATUS_IS_OK(nt_status)) {
2602 return nt_status;
2605 if (r->in.old_val) {
2606 const struct ldb_val *prior_val;
2607 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2608 if (!r->out.old_val) {
2609 return NT_STATUS_NO_MEMORY;
2611 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
2613 if (prior_val && prior_val->length) {
2614 secret.data = prior_val->data;
2615 secret.length = prior_val->length;
2617 /* Encrypt */
2618 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2619 if (!crypt_secret.length) {
2620 return NT_STATUS_NO_MEMORY;
2622 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2623 if (!r->out.old_val->buf) {
2624 return NT_STATUS_NO_MEMORY;
2626 r->out.old_val->buf->size = crypt_secret.length;
2627 r->out.old_val->buf->length = crypt_secret.length;
2628 r->out.old_val->buf->data = crypt_secret.data;
2632 if (r->in.old_mtime) {
2633 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2634 if (!r->out.old_mtime) {
2635 return NT_STATUS_NO_MEMORY;
2637 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
2640 if (r->in.new_val) {
2641 const struct ldb_val *new_val;
2642 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2643 if (!r->out.new_val) {
2644 return NT_STATUS_NO_MEMORY;
2647 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2649 if (new_val && new_val->length) {
2650 secret.data = new_val->data;
2651 secret.length = new_val->length;
2653 /* Encrypt */
2654 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2655 if (!crypt_secret.length) {
2656 return NT_STATUS_NO_MEMORY;
2658 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2659 if (!r->out.new_val->buf) {
2660 return NT_STATUS_NO_MEMORY;
2662 r->out.new_val->buf->length = crypt_secret.length;
2663 r->out.new_val->buf->size = crypt_secret.length;
2664 r->out.new_val->buf->data = crypt_secret.data;
2668 if (r->in.new_mtime) {
2669 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2670 if (!r->out.new_mtime) {
2671 return NT_STATUS_NO_MEMORY;
2673 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2676 return NT_STATUS_OK;
2681 lsa_LookupPrivValue
2683 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
2684 TALLOC_CTX *mem_ctx,
2685 struct lsa_LookupPrivValue *r)
2687 struct dcesrv_handle *h;
2688 struct lsa_policy_state *state;
2689 int id;
2691 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2693 state = h->data;
2695 id = sec_privilege_id(r->in.name->string);
2696 if (id == -1) {
2697 return NT_STATUS_NO_SUCH_PRIVILEGE;
2700 r->out.luid->low = id;
2701 r->out.luid->high = 0;
2703 return NT_STATUS_OK;
2708 lsa_LookupPrivName
2710 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
2711 TALLOC_CTX *mem_ctx,
2712 struct lsa_LookupPrivName *r)
2714 struct dcesrv_handle *h;
2715 struct lsa_policy_state *state;
2716 struct lsa_StringLarge *name;
2717 const char *privname;
2719 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2721 state = h->data;
2723 if (r->in.luid->high != 0) {
2724 return NT_STATUS_NO_SUCH_PRIVILEGE;
2727 privname = sec_privilege_name(r->in.luid->low);
2728 if (privname == NULL) {
2729 return NT_STATUS_NO_SUCH_PRIVILEGE;
2732 name = talloc(mem_ctx, struct lsa_StringLarge);
2733 if (name == NULL) {
2734 return NT_STATUS_NO_MEMORY;
2737 name->string = privname;
2739 *r->out.name = name;
2741 return NT_STATUS_OK;
2746 lsa_LookupPrivDisplayName
2748 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
2749 TALLOC_CTX *mem_ctx,
2750 struct lsa_LookupPrivDisplayName *r)
2752 struct dcesrv_handle *h;
2753 struct lsa_policy_state *state;
2754 struct lsa_StringLarge *disp_name = NULL;
2755 int id;
2757 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2759 state = h->data;
2761 id = sec_privilege_id(r->in.name->string);
2762 if (id == -1) {
2763 return NT_STATUS_NO_SUCH_PRIVILEGE;
2766 disp_name = talloc(mem_ctx, struct lsa_StringLarge);
2767 if (disp_name == NULL) {
2768 return NT_STATUS_NO_MEMORY;
2771 disp_name->string = sec_privilege_display_name(id, &r->in.language_id);
2772 if (disp_name->string == NULL) {
2773 return NT_STATUS_INTERNAL_ERROR;
2776 *r->out.disp_name = disp_name;
2777 *r->out.returned_language_id = 0;
2779 return NT_STATUS_OK;
2784 lsa_EnumAccountsWithUserRight
2786 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
2787 TALLOC_CTX *mem_ctx,
2788 struct lsa_EnumAccountsWithUserRight *r)
2790 struct dcesrv_handle *h;
2791 struct lsa_policy_state *state;
2792 int ret, i;
2793 struct ldb_message **res;
2794 const char * const attrs[] = { "objectSid", NULL};
2795 const char *privname;
2797 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2799 state = h->data;
2801 if (r->in.name == NULL) {
2802 return NT_STATUS_NO_SUCH_PRIVILEGE;
2805 privname = r->in.name->string;
2806 if (sec_privilege_id(privname) == -1) {
2807 return NT_STATUS_NO_SUCH_PRIVILEGE;
2810 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
2811 "privilege=%s", privname);
2812 if (ret == -1) {
2813 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2815 if (ret == 0) {
2816 return NT_STATUS_NO_MORE_ENTRIES;
2819 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2820 if (r->out.sids->sids == NULL) {
2821 return NT_STATUS_NO_MEMORY;
2823 for (i=0;i<ret;i++) {
2824 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2825 res[i], "objectSid");
2826 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2828 r->out.sids->num_sids = ret;
2830 return NT_STATUS_OK;
2835 lsa_AddAccountRights
2837 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
2838 TALLOC_CTX *mem_ctx,
2839 struct lsa_AddAccountRights *r)
2841 struct dcesrv_handle *h;
2842 struct lsa_policy_state *state;
2844 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2846 state = h->data;
2848 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2849 LDB_FLAG_MOD_ADD,
2850 r->in.sid, r->in.rights);
2855 lsa_RemoveAccountRights
2857 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
2858 TALLOC_CTX *mem_ctx,
2859 struct lsa_RemoveAccountRights *r)
2861 struct dcesrv_handle *h;
2862 struct lsa_policy_state *state;
2864 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2866 state = h->data;
2868 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2869 LDB_FLAG_MOD_DELETE,
2870 r->in.sid, r->in.rights);
2875 lsa_StorePrivateData
2877 static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2878 struct lsa_StorePrivateData *r)
2880 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2885 lsa_RetrievePrivateData
2887 static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2888 struct lsa_RetrievePrivateData *r)
2890 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2895 lsa_GetUserName
2897 static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2898 struct lsa_GetUserName *r)
2900 NTSTATUS status = NT_STATUS_OK;
2901 const char *account_name;
2902 const char *authority_name;
2903 struct lsa_String *_account_name;
2904 struct lsa_String *_authority_name = NULL;
2906 /* this is what w2k3 does */
2907 r->out.account_name = r->in.account_name;
2908 r->out.authority_name = r->in.authority_name;
2910 if (r->in.account_name
2911 && *r->in.account_name
2912 /* && *(*r->in.account_name)->string */
2914 return NT_STATUS_INVALID_PARAMETER;
2917 if (r->in.authority_name
2918 && *r->in.authority_name
2919 /* && *(*r->in.authority_name)->string */
2921 return NT_STATUS_INVALID_PARAMETER;
2924 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
2925 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
2927 _account_name = talloc(mem_ctx, struct lsa_String);
2928 NT_STATUS_HAVE_NO_MEMORY(_account_name);
2929 _account_name->string = account_name;
2931 if (r->in.authority_name) {
2932 _authority_name = talloc(mem_ctx, struct lsa_String);
2933 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
2934 _authority_name->string = authority_name;
2937 *r->out.account_name = _account_name;
2938 if (r->out.authority_name) {
2939 *r->out.authority_name = _authority_name;
2942 return status;
2946 lsa_SetInfoPolicy2
2948 static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
2949 TALLOC_CTX *mem_ctx,
2950 struct lsa_SetInfoPolicy2 *r)
2952 /* need to support these */
2953 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2957 lsa_QueryDomainInformationPolicy
2959 static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2960 TALLOC_CTX *mem_ctx,
2961 struct lsa_QueryDomainInformationPolicy *r)
2963 union lsa_DomainInformationPolicy *info;
2965 info = talloc(r->out.info, union lsa_DomainInformationPolicy);
2966 if (!info) {
2967 return NT_STATUS_NO_MEMORY;
2970 switch (r->in.level) {
2971 case LSA_DOMAIN_INFO_POLICY_EFS:
2972 talloc_free(info);
2973 *r->out.info = NULL;
2974 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2975 case LSA_DOMAIN_INFO_POLICY_KERBEROS:
2977 struct lsa_DomainInfoKerberos *k = &info->kerberos_info;
2978 struct smb_krb5_context *smb_krb5_context;
2979 int ret = smb_krb5_init_context(mem_ctx,
2980 dce_call->event_ctx,
2981 dce_call->conn->dce_ctx->lp_ctx,
2982 &smb_krb5_context);
2983 if (ret != 0) {
2984 talloc_free(info);
2985 *r->out.info = NULL;
2986 return NT_STATUS_INTERNAL_ERROR;
2988 k->enforce_restrictions = 0; /* FIXME, details missing from MS-LSAD 2.2.53 */
2989 k->service_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
2990 k->user_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
2991 k->user_tkt_renewaltime = 0; /* Need to find somewhere to store this, and query in KDC too */
2992 k->clock_skew = krb5_get_max_time_skew(smb_krb5_context->krb5_context);
2993 talloc_free(smb_krb5_context);
2994 *r->out.info = info;
2995 return NT_STATUS_OK;
2997 default:
2998 talloc_free(info);
2999 *r->out.info = NULL;
3000 return NT_STATUS_INVALID_INFO_CLASS;
3005 lsa_SetDomInfoPolicy
3007 static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
3008 TALLOC_CTX *mem_ctx,
3009 struct lsa_SetDomainInformationPolicy *r)
3011 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3015 lsa_TestCall
3017 static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
3018 TALLOC_CTX *mem_ctx,
3019 struct lsa_TestCall *r)
3021 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3025 lsa_CREDRWRITE
3027 static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3028 struct lsa_CREDRWRITE *r)
3030 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3035 lsa_CREDRREAD
3037 static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3038 struct lsa_CREDRREAD *r)
3040 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3045 lsa_CREDRENUMERATE
3047 static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3048 struct lsa_CREDRENUMERATE *r)
3050 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3055 lsa_CREDRWRITEDOMAINCREDENTIALS
3057 static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3058 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3060 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3065 lsa_CREDRREADDOMAINCREDENTIALS
3067 static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3068 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3070 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3075 lsa_CREDRDELETE
3077 static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3078 struct lsa_CREDRDELETE *r)
3080 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3085 lsa_CREDRGETTARGETINFO
3087 static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3088 struct lsa_CREDRGETTARGETINFO *r)
3090 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3095 lsa_CREDRPROFILELOADED
3097 static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3098 struct lsa_CREDRPROFILELOADED *r)
3100 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3105 lsa_CREDRGETSESSIONTYPES
3107 static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3108 struct lsa_CREDRGETSESSIONTYPES *r)
3110 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3115 lsa_LSARREGISTERAUDITEVENT
3117 static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3118 struct lsa_LSARREGISTERAUDITEVENT *r)
3120 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3125 lsa_LSARGENAUDITEVENT
3127 static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3128 struct lsa_LSARGENAUDITEVENT *r)
3130 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3135 lsa_LSARUNREGISTERAUDITEVENT
3137 static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3138 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3140 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3145 lsa_lsaRQueryForestTrustInformation
3147 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3148 struct lsa_lsaRQueryForestTrustInformation *r)
3150 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3155 lsa_LSARSETFORESTTRUSTINFORMATION
3157 static NTSTATUS dcesrv_lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3158 struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
3160 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3165 lsa_CREDRRENAME
3167 static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3168 struct lsa_CREDRRENAME *r)
3170 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3176 lsa_LSAROPENPOLICYSCE
3178 static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3179 struct lsa_LSAROPENPOLICYSCE *r)
3181 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3186 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
3188 static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3189 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
3191 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3196 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
3198 static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3199 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
3201 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3206 lsa_LSARADTREPORTSECURITYEVENT
3208 static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3209 struct lsa_LSARADTREPORTSECURITYEVENT *r)
3211 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3215 /* include the generated boilerplate */
3216 #include "librpc/gen_ndr/ndr_lsa_s.c"
3220 /*****************************************
3221 NOTE! The remaining calls below were
3222 removed in w2k3, so the DCESRV_FAULT()
3223 replies are the correct implementation. Do
3224 not try and fill these in with anything else
3225 ******************************************/
3228 dssetup_DsRoleDnsNameToFlatName
3230 static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3231 struct dssetup_DsRoleDnsNameToFlatName *r)
3233 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3238 dssetup_DsRoleDcAsDc
3240 static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3241 struct dssetup_DsRoleDcAsDc *r)
3243 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3248 dssetup_DsRoleDcAsReplica
3250 static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3251 struct dssetup_DsRoleDcAsReplica *r)
3253 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3258 dssetup_DsRoleDemoteDc
3260 static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3261 struct dssetup_DsRoleDemoteDc *r)
3263 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3268 dssetup_DsRoleGetDcOperationProgress
3270 static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3271 struct dssetup_DsRoleGetDcOperationProgress *r)
3273 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3278 dssetup_DsRoleGetDcOperationResults
3280 static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3281 struct dssetup_DsRoleGetDcOperationResults *r)
3283 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3288 dssetup_DsRoleCancel
3290 static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3291 struct dssetup_DsRoleCancel *r)
3293 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3298 dssetup_DsRoleServerSaveStateForUpgrade
3300 static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3301 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
3303 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3308 dssetup_DsRoleUpgradeDownlevelServer
3310 static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3311 struct dssetup_DsRoleUpgradeDownlevelServer *r)
3313 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3318 dssetup_DsRoleAbortDownlevelServerUpgrade
3320 static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3321 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
3323 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3327 /* include the generated boilerplate */
3328 #include "librpc/gen_ndr/ndr_dssetup_s.c"
3330 NTSTATUS dcerpc_server_lsa_init(void)
3332 NTSTATUS ret;
3334 ret = dcerpc_server_dssetup_init();
3335 if (!NT_STATUS_IS_OK(ret)) {
3336 return ret;
3338 ret = dcerpc_server_lsarpc_init();
3339 if (!NT_STATUS_IS_OK(ret)) {
3340 return ret;
3342 return ret;