LSA Patch for User Manager
[Samba.git] / source4 / rpc_server / lsa / dcesrv_lsa.c
blob84f11ef3a8f7564b6c762acb9da88017004e8a0a
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;
438 r->out.info = NULL;
440 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
442 state = h->data;
444 r->out.info = talloc(mem_ctx, union lsa_PolicyInformation);
445 if (!r->out.info) {
446 return NT_STATUS_NO_MEMORY;
449 ZERO_STRUCTP(r->out.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(r->out.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(r->out.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(r->out.info->pd);
463 return NT_STATUS_OK;
465 case LSA_POLICY_INFO_DOMAIN:
466 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &r->out.info->domain);
467 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
468 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &r->out.info->account_domain);
469 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
470 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &r->out.info->l_account_domain);
473 case LSA_POLICY_INFO_ROLE:
474 r->out.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, &r->out.info->dns);
481 case LSA_POLICY_INFO_REPLICA:
482 ZERO_STRUCT(r->out.info->replica);
483 return NT_STATUS_OK;
485 case LSA_POLICY_INFO_QUOTA:
486 ZERO_STRUCT(r->out.info->quota);
487 return NT_STATUS_OK;
489 case LSA_POLICY_INFO_MOD:
490 case LSA_POLICY_INFO_AUDIT_FULL_SET:
491 /* windows gives INVALID_PARAMETER */
492 r->out.info = NULL;
493 return NT_STATUS_INVALID_PARAMETER;
496 r->out.info = NULL;
497 return NT_STATUS_INVALID_INFO_CLASS;
501 lsa_QueryInfoPolicy
503 static NTSTATUS dcesrv_lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
504 struct lsa_QueryInfoPolicy *r)
506 struct lsa_QueryInfoPolicy2 r2;
507 NTSTATUS status;
509 ZERO_STRUCT(r2);
511 r2.in.handle = r->in.handle;
512 r2.in.level = r->in.level;
514 status = dcesrv_lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
516 r->out.info = r2.out.info;
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 struct dcesrv_handle *h;
1317 struct lsa_trusted_domain_state *trusted_domain_state;
1318 struct ldb_message *msg;
1319 int ret;
1320 struct ldb_message **res;
1321 const char *attrs[] = {
1322 "flatname",
1323 "trustPartner",
1324 "securityIdentifier",
1325 "trustDirection",
1326 "trustType",
1327 "trustAttributes",
1328 "msDs-supportedEncryptionTypes",
1329 NULL
1332 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
1334 trusted_domain_state = talloc_get_type(h->data, struct lsa_trusted_domain_state);
1336 /* pull all the user attributes */
1337 ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
1338 trusted_domain_state->trusted_domain_dn, &res, attrs);
1339 if (ret != 1) {
1340 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1342 msg = res[0];
1344 r->out.info = talloc(mem_ctx, union lsa_TrustedDomainInfo);
1345 if (!r->out.info) {
1346 return NT_STATUS_NO_MEMORY;
1348 switch (r->in.level) {
1349 case LSA_TRUSTED_DOMAIN_INFO_NAME:
1350 r->out.info->name.netbios_name.string
1351 = samdb_result_string(msg, "flatname", NULL);
1352 break;
1353 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1354 r->out.info->posix_offset.posix_offset
1355 = samdb_result_uint(msg, "posixOffset", 0);
1356 break;
1357 #if 0 /* Win2k3 doesn't implement this */
1358 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
1359 r->out.info->info_basic.netbios_name.string
1360 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1361 r->out.info->info_basic.sid
1362 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1363 break;
1364 #endif
1365 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1366 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->info_ex);
1368 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1369 ZERO_STRUCT(r->out.info->full_info);
1370 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->full_info.info_ex);
1372 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
1373 ZERO_STRUCT(r->out.info->full_info2_internal);
1374 r->out.info->full_info2_internal.posix_offset.posix_offset
1375 = samdb_result_uint(msg, "posixOffset", 0);
1376 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->full_info2_internal.info.info_ex);
1378 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES:
1379 r->out.info->enc_types.enc_types
1380 = samdb_result_uint(msg, "msDs-supportedEncryptionTypes", KERB_ENCTYPE_RC4_HMAC_MD5);
1381 break;
1383 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
1384 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
1385 /* oops, we don't want to return the info after all */
1386 talloc_free(r->out.info);
1387 r->out.info = NULL;
1388 return NT_STATUS_INVALID_PARAMETER;
1389 default:
1390 /* oops, we don't want to return the info after all */
1391 talloc_free(r->out.info);
1392 r->out.info = NULL;
1393 return NT_STATUS_INVALID_INFO_CLASS;
1396 return NT_STATUS_OK;
1401 lsa_QueryTrustedDomainInfoBySid
1403 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1404 struct lsa_QueryTrustedDomainInfoBySid *r)
1406 NTSTATUS status;
1407 struct lsa_OpenTrustedDomain open;
1408 struct lsa_QueryTrustedDomainInfo query;
1409 struct dcesrv_handle *h;
1410 open.in.handle = r->in.handle;
1411 open.in.sid = r->in.dom_sid;
1412 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1413 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1414 if (!open.out.trustdom_handle) {
1415 return NT_STATUS_NO_MEMORY;
1417 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
1418 if (!NT_STATUS_IS_OK(status)) {
1419 return status;
1422 /* Ensure this handle goes away at the end of this call */
1423 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1424 talloc_steal(mem_ctx, h);
1426 query.in.trustdom_handle = open.out.trustdom_handle;
1427 query.in.level = r->in.level;
1428 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1429 if (!NT_STATUS_IS_OK(status)) {
1430 return status;
1433 r->out.info = query.out.info;
1434 return NT_STATUS_OK;
1438 lsa_SetTrustedDomainInfoByName
1440 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1441 TALLOC_CTX *mem_ctx,
1442 struct lsa_SetTrustedDomainInfoByName *r)
1444 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1448 lsa_QueryTrustedDomainInfoByName
1450 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1451 TALLOC_CTX *mem_ctx,
1452 struct lsa_QueryTrustedDomainInfoByName *r)
1454 NTSTATUS status;
1455 struct lsa_OpenTrustedDomainByName open;
1456 struct lsa_QueryTrustedDomainInfo query;
1457 struct dcesrv_handle *h;
1458 open.in.handle = r->in.handle;
1459 open.in.name = r->in.trusted_domain;
1460 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1461 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1462 if (!open.out.trustdom_handle) {
1463 return NT_STATUS_NO_MEMORY;
1465 status = dcesrv_lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &open);
1466 if (!NT_STATUS_IS_OK(status)) {
1467 return status;
1470 /* Ensure this handle goes away at the end of this call */
1471 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1472 talloc_steal(mem_ctx, h);
1474 query.in.trustdom_handle = open.out.trustdom_handle;
1475 query.in.level = r->in.level;
1476 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1477 if (!NT_STATUS_IS_OK(status)) {
1478 return status;
1481 r->out.info = query.out.info;
1482 return NT_STATUS_OK;
1486 lsa_CloseTrustedDomainEx
1488 static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
1489 TALLOC_CTX *mem_ctx,
1490 struct lsa_CloseTrustedDomainEx *r)
1492 /* The result of a bad hair day from an IDL programmer? Not
1493 * implmented in Win2k3. You should always just lsa_Close
1494 * anyway. */
1495 return NT_STATUS_NOT_IMPLEMENTED;
1500 comparison function for sorting lsa_DomainInformation array
1502 static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
1504 return strcasecmp_m(e1->name.string, e2->name.string);
1508 lsa_EnumTrustDom
1510 static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1511 struct lsa_EnumTrustDom *r)
1513 struct dcesrv_handle *policy_handle;
1514 struct lsa_DomainInfo *entries;
1515 struct lsa_policy_state *policy_state;
1516 struct ldb_message **domains;
1517 const char *attrs[] = {
1518 "flatname",
1519 "securityIdentifier",
1520 NULL
1524 int count, i;
1526 *r->out.resume_handle = 0;
1528 r->out.domains->domains = NULL;
1529 r->out.domains->count = 0;
1531 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1533 policy_state = policy_handle->data;
1535 /* search for all users in this domain. This could possibly be cached and
1536 resumed based on resume_key */
1537 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1538 "objectclass=trustedDomain");
1539 if (count == -1) {
1540 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1543 /* convert to lsa_TrustInformation format */
1544 entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
1545 if (!entries) {
1546 return NT_STATUS_NO_MEMORY;
1548 for (i=0;i<count;i++) {
1549 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
1550 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
1553 /* sort the results by name */
1554 qsort(entries, count, sizeof(*entries),
1555 (comparison_fn_t)compare_DomainInfo);
1557 if (*r->in.resume_handle >= count) {
1558 *r->out.resume_handle = -1;
1560 return NT_STATUS_NO_MORE_ENTRIES;
1563 /* return the rest, limit by max_size. Note that we
1564 use the w2k3 element size value of 60 */
1565 r->out.domains->count = count - *r->in.resume_handle;
1566 r->out.domains->count = MIN(r->out.domains->count,
1567 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
1569 r->out.domains->domains = entries + *r->in.resume_handle;
1570 r->out.domains->count = r->out.domains->count;
1572 if (r->out.domains->count < count - *r->in.resume_handle) {
1573 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1574 return STATUS_MORE_ENTRIES;
1577 return NT_STATUS_OK;
1581 comparison function for sorting lsa_DomainInformation array
1583 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
1585 return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
1589 lsa_EnumTrustedDomainsEx
1591 static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1592 struct lsa_EnumTrustedDomainsEx *r)
1594 struct dcesrv_handle *policy_handle;
1595 struct lsa_TrustDomainInfoInfoEx *entries;
1596 struct lsa_policy_state *policy_state;
1597 struct ldb_message **domains;
1598 const char *attrs[] = {
1599 "flatname",
1600 "trustPartner",
1601 "securityIdentifier",
1602 "trustDirection",
1603 "trustType",
1604 "trustAttributes",
1605 NULL
1607 NTSTATUS nt_status;
1609 int count, i;
1611 *r->out.resume_handle = 0;
1613 r->out.domains->domains = NULL;
1614 r->out.domains->count = 0;
1616 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1618 policy_state = policy_handle->data;
1620 /* search for all users in this domain. This could possibly be cached and
1621 resumed based on resume_key */
1622 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1623 "objectclass=trustedDomain");
1624 if (count == -1) {
1625 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1628 /* convert to lsa_DomainInformation format */
1629 entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
1630 if (!entries) {
1631 return NT_STATUS_NO_MEMORY;
1633 for (i=0;i<count;i++) {
1634 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
1635 if (!NT_STATUS_IS_OK(nt_status)) {
1636 return nt_status;
1640 /* sort the results by name */
1641 qsort(entries, count, sizeof(*entries),
1642 (comparison_fn_t)compare_TrustDomainInfoInfoEx);
1644 if (*r->in.resume_handle >= count) {
1645 *r->out.resume_handle = -1;
1647 return NT_STATUS_NO_MORE_ENTRIES;
1650 /* return the rest, limit by max_size. Note that we
1651 use the w2k3 element size value of 60 */
1652 r->out.domains->count = count - *r->in.resume_handle;
1653 r->out.domains->count = MIN(r->out.domains->count,
1654 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
1656 r->out.domains->domains = entries + *r->in.resume_handle;
1657 r->out.domains->count = r->out.domains->count;
1659 if (r->out.domains->count < count - *r->in.resume_handle) {
1660 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1661 return STATUS_MORE_ENTRIES;
1664 return NT_STATUS_OK;
1669 lsa_OpenAccount
1671 static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1672 struct lsa_OpenAccount *r)
1674 struct dcesrv_handle *h, *ah;
1675 struct lsa_policy_state *state;
1676 struct lsa_account_state *astate;
1678 ZERO_STRUCTP(r->out.acct_handle);
1680 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1682 state = h->data;
1684 astate = talloc(dce_call->conn, struct lsa_account_state);
1685 if (astate == NULL) {
1686 return NT_STATUS_NO_MEMORY;
1689 astate->account_sid = dom_sid_dup(astate, r->in.sid);
1690 if (astate->account_sid == NULL) {
1691 talloc_free(astate);
1692 return NT_STATUS_NO_MEMORY;
1695 astate->policy = talloc_reference(astate, state);
1696 astate->access_mask = r->in.access_mask;
1698 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
1699 if (!ah) {
1700 talloc_free(astate);
1701 return NT_STATUS_NO_MEMORY;
1704 ah->data = talloc_steal(ah, astate);
1706 *r->out.acct_handle = ah->wire_handle;
1708 return NT_STATUS_OK;
1713 lsa_EnumPrivsAccount
1715 static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
1716 TALLOC_CTX *mem_ctx,
1717 struct lsa_EnumPrivsAccount *r)
1719 struct dcesrv_handle *h;
1720 struct lsa_account_state *astate;
1721 int ret, i;
1722 struct ldb_message **res;
1723 const char * const attrs[] = { "privilege", NULL};
1724 struct ldb_message_element *el;
1725 const char *sidstr;
1727 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1729 astate = h->data;
1731 r->out.privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
1732 r->out.privs->count = 0;
1733 r->out.privs->unknown = 0;
1734 r->out.privs->set = NULL;
1736 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
1737 if (sidstr == NULL) {
1738 return NT_STATUS_NO_MEMORY;
1741 ret = gendb_search(astate->policy->sam_ldb, mem_ctx, NULL, &res, attrs,
1742 "objectSid=%s", sidstr);
1743 if (ret != 1) {
1744 return NT_STATUS_OK;
1747 el = ldb_msg_find_element(res[0], "privilege");
1748 if (el == NULL || el->num_values == 0) {
1749 return NT_STATUS_OK;
1752 r->out.privs->set = talloc_array(r->out.privs,
1753 struct lsa_LUIDAttribute, el->num_values);
1754 if (r->out.privs->set == NULL) {
1755 return NT_STATUS_NO_MEMORY;
1758 for (i=0;i<el->num_values;i++) {
1759 int id = sec_privilege_id((const char *)el->values[i].data);
1760 if (id == -1) {
1761 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1763 r->out.privs->set[i].attribute = 0;
1764 r->out.privs->set[i].luid.low = id;
1765 r->out.privs->set[i].luid.high = 0;
1768 r->out.privs->count = el->num_values;
1770 return NT_STATUS_OK;
1774 lsa_EnumAccountRights
1776 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
1777 TALLOC_CTX *mem_ctx,
1778 struct lsa_EnumAccountRights *r)
1780 struct dcesrv_handle *h;
1781 struct lsa_policy_state *state;
1782 int ret, i;
1783 struct ldb_message **res;
1784 const char * const attrs[] = { "privilege", NULL};
1785 const char *sidstr;
1786 struct ldb_message_element *el;
1788 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1790 state = h->data;
1792 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
1793 if (sidstr == NULL) {
1794 return NT_STATUS_NO_MEMORY;
1797 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
1798 "(&(objectSid=%s)(privilege=*))", sidstr);
1799 if (ret == 0) {
1800 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1802 if (ret > 1) {
1803 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1805 if (ret == -1) {
1806 DEBUG(3, ("searching for account rights for SID: %s failed: %s",
1807 dom_sid_string(mem_ctx, r->in.sid),
1808 ldb_errstring(state->sam_ldb)));
1809 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1812 el = ldb_msg_find_element(res[0], "privilege");
1813 if (el == NULL || el->num_values == 0) {
1814 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1817 r->out.rights->count = el->num_values;
1818 r->out.rights->names = talloc_array(r->out.rights,
1819 struct lsa_StringLarge, r->out.rights->count);
1820 if (r->out.rights->names == NULL) {
1821 return NT_STATUS_NO_MEMORY;
1824 for (i=0;i<el->num_values;i++) {
1825 r->out.rights->names[i].string = (const char *)el->values[i].data;
1828 return NT_STATUS_OK;
1834 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
1836 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
1837 TALLOC_CTX *mem_ctx,
1838 struct lsa_policy_state *state,
1839 int ldb_flag,
1840 struct dom_sid *sid,
1841 const struct lsa_RightSet *rights)
1843 const char *sidstr;
1844 struct ldb_message *msg;
1845 struct ldb_message_element *el;
1846 int i, ret;
1847 struct lsa_EnumAccountRights r2;
1849 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, sid);
1850 if (sidstr == NULL) {
1851 return NT_STATUS_NO_MEMORY;
1854 msg = ldb_msg_new(mem_ctx);
1855 if (msg == NULL) {
1856 return NT_STATUS_NO_MEMORY;
1859 msg->dn = samdb_search_dn(state->sam_ldb, mem_ctx,
1860 NULL, "objectSid=%s", sidstr);
1861 if (msg->dn == NULL) {
1862 NTSTATUS status;
1863 if (ldb_flag == LDB_FLAG_MOD_DELETE) {
1864 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1866 status = samdb_create_foreign_security_principal(state->sam_ldb, mem_ctx,
1867 sid, &msg->dn);
1868 if (!NT_STATUS_IS_OK(status)) {
1869 return status;
1871 return NT_STATUS_NO_SUCH_USER;
1874 if (ldb_msg_add_empty(msg, "privilege", ldb_flag, NULL)) {
1875 return NT_STATUS_NO_MEMORY;
1878 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1879 NTSTATUS status;
1881 r2.in.handle = &state->handle->wire_handle;
1882 r2.in.sid = sid;
1883 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
1885 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1886 if (!NT_STATUS_IS_OK(status)) {
1887 ZERO_STRUCTP(r2.out.rights);
1891 for (i=0;i<rights->count;i++) {
1892 if (sec_privilege_id(rights->names[i].string) == -1) {
1893 return NT_STATUS_NO_SUCH_PRIVILEGE;
1896 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1897 int j;
1898 for (j=0;j<r2.out.rights->count;j++) {
1899 if (strcasecmp_m(r2.out.rights->names[j].string,
1900 rights->names[i].string) == 0) {
1901 break;
1904 if (j != r2.out.rights->count) continue;
1907 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
1908 if (ret != LDB_SUCCESS) {
1909 return NT_STATUS_NO_MEMORY;
1913 el = ldb_msg_find_element(msg, "privilege");
1914 if (!el) {
1915 return NT_STATUS_OK;
1918 ret = ldb_modify(state->sam_ldb, msg);
1919 if (ret != 0) {
1920 if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1921 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1923 DEBUG(3, ("Could not %s attributes from %s: %s",
1924 ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add",
1925 ldb_dn_get_linearized(msg->dn), ldb_errstring(state->sam_ldb)));
1926 return NT_STATUS_UNEXPECTED_IO_ERROR;
1929 return NT_STATUS_OK;
1933 lsa_AddPrivilegesToAccount
1935 static NTSTATUS dcesrv_lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1936 struct lsa_AddPrivilegesToAccount *r)
1938 struct lsa_RightSet rights;
1939 struct dcesrv_handle *h;
1940 struct lsa_account_state *astate;
1941 int i;
1943 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1945 astate = h->data;
1947 rights.count = r->in.privs->count;
1948 rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
1949 if (rights.names == NULL) {
1950 return NT_STATUS_NO_MEMORY;
1952 for (i=0;i<rights.count;i++) {
1953 int id = r->in.privs->set[i].luid.low;
1954 if (r->in.privs->set[i].luid.high) {
1955 return NT_STATUS_NO_SUCH_PRIVILEGE;
1957 rights.names[i].string = sec_privilege_name(id);
1958 if (rights.names[i].string == NULL) {
1959 return NT_STATUS_NO_SUCH_PRIVILEGE;
1963 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1964 LDB_FLAG_MOD_ADD, astate->account_sid,
1965 &rights);
1970 lsa_RemovePrivilegesFromAccount
1972 static NTSTATUS dcesrv_lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1973 struct lsa_RemovePrivilegesFromAccount *r)
1975 struct lsa_RightSet *rights;
1976 struct dcesrv_handle *h;
1977 struct lsa_account_state *astate;
1978 int i;
1980 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1982 astate = h->data;
1984 rights = talloc(mem_ctx, struct lsa_RightSet);
1986 if (r->in.remove_all == 1 &&
1987 r->in.privs == NULL) {
1988 struct lsa_EnumAccountRights r2;
1989 NTSTATUS status;
1991 r2.in.handle = &astate->policy->handle->wire_handle;
1992 r2.in.sid = astate->account_sid;
1993 r2.out.rights = rights;
1995 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1996 if (!NT_STATUS_IS_OK(status)) {
1997 return status;
2000 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2001 LDB_FLAG_MOD_DELETE, astate->account_sid,
2002 r2.out.rights);
2005 if (r->in.remove_all != 0) {
2006 return NT_STATUS_INVALID_PARAMETER;
2009 rights->count = r->in.privs->count;
2010 rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
2011 if (rights->names == NULL) {
2012 return NT_STATUS_NO_MEMORY;
2014 for (i=0;i<rights->count;i++) {
2015 int id = r->in.privs->set[i].luid.low;
2016 if (r->in.privs->set[i].luid.high) {
2017 return NT_STATUS_NO_SUCH_PRIVILEGE;
2019 rights->names[i].string = sec_privilege_name(id);
2020 if (rights->names[i].string == NULL) {
2021 return NT_STATUS_NO_SUCH_PRIVILEGE;
2025 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2026 LDB_FLAG_MOD_DELETE, astate->account_sid,
2027 rights);
2032 lsa_GetQuotasForAccount
2034 static NTSTATUS dcesrv_lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2035 struct lsa_GetQuotasForAccount *r)
2037 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2042 lsa_SetQuotasForAccount
2044 static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2045 struct lsa_SetQuotasForAccount *r)
2047 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2052 lsa_GetSystemAccessAccount
2054 static NTSTATUS dcesrv_lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2055 struct lsa_GetSystemAccessAccount *r)
2057 int i;
2058 NTSTATUS status;
2059 struct lsa_EnumPrivsAccount enumPrivs;
2061 enumPrivs.in.handle = r->in.handle;
2063 status = dcesrv_lsa_EnumPrivsAccount(dce_call, mem_ctx, &enumPrivs);
2064 if (!NT_STATUS_IS_OK(status)) {
2065 return status;
2068 *(r->out.access_mask) = 0x00000000;
2070 for (i = 0; i < enumPrivs.out.privs->count; i++) {
2071 int priv = enumPrivs.out.privs->set[i].luid.low;
2073 switch (priv) {
2074 case SEC_PRIV_INTERACTIVE_LOGON:
2075 *(r->out.access_mask) |= LSA_POLICY_MODE_INTERACTIVE;
2076 break;
2077 case SEC_PRIV_NETWORK_LOGON:
2078 *(r->out.access_mask) |= LSA_POLICY_MODE_NETWORK;
2079 break;
2080 case SEC_PRIV_REMOTE_INTERACTIVE_LOGON:
2081 *(r->out.access_mask) |= LSA_POLICY_MODE_REMOTE_INTERACTIVE;
2082 break;
2086 return NT_STATUS_OK;
2091 lsa_SetSystemAccessAccount
2093 static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2094 struct lsa_SetSystemAccessAccount *r)
2096 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2101 lsa_CreateSecret
2103 static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2104 struct lsa_CreateSecret *r)
2106 struct dcesrv_handle *policy_handle;
2107 struct lsa_policy_state *policy_state;
2108 struct lsa_secret_state *secret_state;
2109 struct dcesrv_handle *handle;
2110 struct ldb_message **msgs, *msg;
2111 const char *errstr;
2112 const char *attrs[] = {
2113 NULL
2116 const char *name;
2118 int ret;
2120 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2121 ZERO_STRUCTP(r->out.sec_handle);
2123 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2125 case SECURITY_SYSTEM:
2126 case SECURITY_ADMINISTRATOR:
2127 break;
2128 default:
2129 /* Users and annonymous are not allowed create secrets */
2130 return NT_STATUS_ACCESS_DENIED;
2133 policy_state = policy_handle->data;
2135 if (!r->in.name.string) {
2136 return NT_STATUS_INVALID_PARAMETER;
2139 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2140 if (!secret_state) {
2141 return NT_STATUS_NO_MEMORY;
2143 secret_state->policy = policy_state;
2145 msg = ldb_msg_new(mem_ctx);
2146 if (msg == NULL) {
2147 return NT_STATUS_NO_MEMORY;
2150 if (strncmp("G$", r->in.name.string, 2) == 0) {
2151 const char *name2;
2152 name = &r->in.name.string[2];
2153 /* 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) */
2154 secret_state->sam_ldb = talloc_reference(secret_state,
2155 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)));
2156 secret_state->global = true;
2158 if (strlen(name) < 1) {
2159 return NT_STATUS_INVALID_PARAMETER;
2162 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
2163 /* search for the secret record */
2164 ret = gendb_search(secret_state->sam_ldb,
2165 mem_ctx, policy_state->system_dn, &msgs, attrs,
2166 "(&(cn=%s)(objectclass=secret))",
2167 name2);
2168 if (ret > 0) {
2169 return NT_STATUS_OBJECT_NAME_COLLISION;
2172 if (ret == -1) {
2173 DEBUG(0,("Failure searching for CN=%s: %s\n",
2174 name2, ldb_errstring(secret_state->sam_ldb)));
2175 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2178 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
2179 if (!name2 || ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
2180 return NT_STATUS_NO_MEMORY;
2183 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
2185 } else {
2186 secret_state->global = false;
2188 name = r->in.name.string;
2189 if (strlen(name) < 1) {
2190 return NT_STATUS_INVALID_PARAMETER;
2193 secret_state->sam_ldb = talloc_reference(secret_state,
2194 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
2195 /* search for the secret record */
2196 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2197 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2198 &msgs, attrs,
2199 "(&(cn=%s)(objectclass=secret))",
2200 ldb_binary_encode_string(mem_ctx, name));
2201 if (ret > 0) {
2202 return NT_STATUS_OBJECT_NAME_COLLISION;
2205 if (ret == -1) {
2206 DEBUG(0,("Failure searching for CN=%s: %s\n",
2207 name, ldb_errstring(secret_state->sam_ldb)));
2208 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2211 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name);
2212 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
2215 /* pull in all the template attributes. Note this is always from the global samdb */
2216 ret = samdb_copy_template(secret_state->policy->sam_ldb, msg,
2217 "secret", &errstr);
2218 if (ret != 0) {
2219 DEBUG(0,("Failed to load TemplateSecret from samdb: %s\n",
2220 errstr));
2221 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2224 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
2226 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
2228 /* create the secret */
2229 ret = ldb_add(secret_state->sam_ldb, msg);
2230 if (ret != 0) {
2231 DEBUG(0,("Failed to create secret record %s: %s\n",
2232 ldb_dn_get_linearized(msg->dn),
2233 ldb_errstring(secret_state->sam_ldb)));
2234 return NT_STATUS_ACCESS_DENIED;
2237 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2238 if (!handle) {
2239 return NT_STATUS_NO_MEMORY;
2242 handle->data = talloc_steal(handle, secret_state);
2244 secret_state->access_mask = r->in.access_mask;
2245 secret_state->policy = talloc_reference(secret_state, policy_state);
2247 *r->out.sec_handle = handle->wire_handle;
2249 return NT_STATUS_OK;
2254 lsa_OpenSecret
2256 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2257 struct lsa_OpenSecret *r)
2259 struct dcesrv_handle *policy_handle;
2261 struct lsa_policy_state *policy_state;
2262 struct lsa_secret_state *secret_state;
2263 struct dcesrv_handle *handle;
2264 struct ldb_message **msgs;
2265 const char *attrs[] = {
2266 NULL
2269 const char *name;
2271 int ret;
2273 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2274 ZERO_STRUCTP(r->out.sec_handle);
2275 policy_state = policy_handle->data;
2277 if (!r->in.name.string) {
2278 return NT_STATUS_INVALID_PARAMETER;
2281 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2283 case SECURITY_SYSTEM:
2284 case SECURITY_ADMINISTRATOR:
2285 break;
2286 default:
2287 /* Users and annonymous are not allowed to access secrets */
2288 return NT_STATUS_ACCESS_DENIED;
2291 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2292 if (!secret_state) {
2293 return NT_STATUS_NO_MEMORY;
2295 secret_state->policy = policy_state;
2297 if (strncmp("G$", r->in.name.string, 2) == 0) {
2298 name = &r->in.name.string[2];
2299 /* 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) */
2300 secret_state->sam_ldb = talloc_reference(secret_state,
2301 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)));
2302 secret_state->global = true;
2304 if (strlen(name) < 1) {
2305 return NT_STATUS_INVALID_PARAMETER;
2308 /* search for the secret record */
2309 ret = gendb_search(secret_state->sam_ldb,
2310 mem_ctx, policy_state->system_dn, &msgs, attrs,
2311 "(&(cn=%s Secret)(objectclass=secret))",
2312 ldb_binary_encode_string(mem_ctx, name));
2313 if (ret == 0) {
2314 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2317 if (ret != 1) {
2318 DEBUG(0,("Found %d records matching DN %s\n", ret,
2319 ldb_dn_get_linearized(policy_state->system_dn)));
2320 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2323 } else {
2324 secret_state->global = false;
2325 secret_state->sam_ldb = talloc_reference(secret_state,
2326 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
2328 name = r->in.name.string;
2329 if (strlen(name) < 1) {
2330 return NT_STATUS_INVALID_PARAMETER;
2333 /* search for the secret record */
2334 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2335 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2336 &msgs, attrs,
2337 "(&(cn=%s)(objectclass=secret))",
2338 ldb_binary_encode_string(mem_ctx, name));
2339 if (ret == 0) {
2340 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2343 if (ret != 1) {
2344 DEBUG(0,("Found %d records matching CN=%s\n",
2345 ret, ldb_binary_encode_string(mem_ctx, name)));
2346 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2350 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
2352 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2353 if (!handle) {
2354 return NT_STATUS_NO_MEMORY;
2357 handle->data = talloc_steal(handle, secret_state);
2359 secret_state->access_mask = r->in.access_mask;
2360 secret_state->policy = talloc_reference(secret_state, policy_state);
2362 *r->out.sec_handle = handle->wire_handle;
2364 return NT_STATUS_OK;
2369 lsa_SetSecret
2371 static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2372 struct lsa_SetSecret *r)
2375 struct dcesrv_handle *h;
2376 struct lsa_secret_state *secret_state;
2377 struct ldb_message *msg;
2378 DATA_BLOB session_key;
2379 DATA_BLOB crypt_secret, secret;
2380 struct ldb_val val;
2381 int ret;
2382 NTSTATUS status = NT_STATUS_OK;
2384 struct timeval now = timeval_current();
2385 NTTIME nt_now = timeval_to_nttime(&now);
2387 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2389 secret_state = h->data;
2391 msg = ldb_msg_new(mem_ctx);
2392 if (msg == NULL) {
2393 return NT_STATUS_NO_MEMORY;
2396 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
2397 if (!msg->dn) {
2398 return NT_STATUS_NO_MEMORY;
2400 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2401 if (!NT_STATUS_IS_OK(status)) {
2402 return status;
2405 if (r->in.old_val) {
2406 /* Decrypt */
2407 crypt_secret.data = r->in.old_val->data;
2408 crypt_secret.length = r->in.old_val->size;
2410 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2411 if (!NT_STATUS_IS_OK(status)) {
2412 return status;
2415 val.data = secret.data;
2416 val.length = secret.length;
2418 /* set value */
2419 if (samdb_msg_add_value(secret_state->sam_ldb,
2420 mem_ctx, msg, "priorValue", &val) != 0) {
2421 return NT_STATUS_NO_MEMORY;
2424 /* set old value mtime */
2425 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2426 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
2427 return NT_STATUS_NO_MEMORY;
2430 } else {
2431 /* If the old value is not set, then migrate the
2432 * current value to the old value */
2433 const struct ldb_val *old_val;
2434 NTTIME last_set_time;
2435 struct ldb_message **res;
2436 const char *attrs[] = {
2437 "currentValue",
2438 "lastSetTime",
2439 NULL
2442 /* search for the secret record */
2443 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
2444 secret_state->secret_dn, &res, attrs);
2445 if (ret == 0) {
2446 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2449 if (ret != 1) {
2450 DEBUG(0,("Found %d records matching dn=%s\n", ret,
2451 ldb_dn_get_linearized(secret_state->secret_dn)));
2452 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2455 old_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2456 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2458 if (old_val) {
2459 /* set old value */
2460 if (samdb_msg_add_value(secret_state->sam_ldb,
2461 mem_ctx, msg, "priorValue",
2462 old_val) != 0) {
2463 return NT_STATUS_NO_MEMORY;
2465 } else {
2466 if (samdb_msg_add_delete(secret_state->sam_ldb,
2467 mem_ctx, msg, "priorValue")) {
2468 return NT_STATUS_NO_MEMORY;
2473 /* set old value mtime */
2474 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2475 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2476 mem_ctx, msg, "priorSetTime", last_set_time) != 0) {
2477 return NT_STATUS_NO_MEMORY;
2479 } else {
2480 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2481 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
2482 return NT_STATUS_NO_MEMORY;
2487 if (r->in.new_val) {
2488 /* Decrypt */
2489 crypt_secret.data = r->in.new_val->data;
2490 crypt_secret.length = r->in.new_val->size;
2492 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2493 if (!NT_STATUS_IS_OK(status)) {
2494 return status;
2497 val.data = secret.data;
2498 val.length = secret.length;
2500 /* set value */
2501 if (samdb_msg_add_value(secret_state->sam_ldb,
2502 mem_ctx, msg, "currentValue", &val) != 0) {
2503 return NT_STATUS_NO_MEMORY;
2506 /* set new value mtime */
2507 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2508 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2509 return NT_STATUS_NO_MEMORY;
2512 } else {
2513 /* NULL out the NEW value */
2514 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2515 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2516 return NT_STATUS_NO_MEMORY;
2518 if (samdb_msg_add_delete(secret_state->sam_ldb,
2519 mem_ctx, msg, "currentValue")) {
2520 return NT_STATUS_NO_MEMORY;
2524 /* modify the samdb record */
2525 ret = samdb_replace(secret_state->sam_ldb, mem_ctx, msg);
2526 if (ret != 0) {
2527 /* we really need samdb.c to return NTSTATUS */
2528 return NT_STATUS_UNSUCCESSFUL;
2531 return NT_STATUS_OK;
2536 lsa_QuerySecret
2538 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2539 struct lsa_QuerySecret *r)
2541 struct dcesrv_handle *h;
2542 struct lsa_secret_state *secret_state;
2543 struct ldb_message *msg;
2544 DATA_BLOB session_key;
2545 DATA_BLOB crypt_secret, secret;
2546 int ret;
2547 struct ldb_message **res;
2548 const char *attrs[] = {
2549 "currentValue",
2550 "priorValue",
2551 "lastSetTime",
2552 "priorSetTime",
2553 NULL
2556 NTSTATUS nt_status;
2558 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2560 /* Ensure user is permitted to read this... */
2561 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2563 case SECURITY_SYSTEM:
2564 case SECURITY_ADMINISTRATOR:
2565 break;
2566 default:
2567 /* Users and annonymous are not allowed to read secrets */
2568 return NT_STATUS_ACCESS_DENIED;
2571 secret_state = h->data;
2573 /* pull all the user attributes */
2574 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2575 secret_state->secret_dn, &res, attrs);
2576 if (ret != 1) {
2577 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2579 msg = res[0];
2581 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2582 if (!NT_STATUS_IS_OK(nt_status)) {
2583 return nt_status;
2586 if (r->in.old_val) {
2587 const struct ldb_val *prior_val;
2588 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2589 if (!r->out.old_val) {
2590 return NT_STATUS_NO_MEMORY;
2592 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
2594 if (prior_val && prior_val->length) {
2595 secret.data = prior_val->data;
2596 secret.length = prior_val->length;
2598 /* Encrypt */
2599 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2600 if (!crypt_secret.length) {
2601 return NT_STATUS_NO_MEMORY;
2603 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2604 if (!r->out.old_val->buf) {
2605 return NT_STATUS_NO_MEMORY;
2607 r->out.old_val->buf->size = crypt_secret.length;
2608 r->out.old_val->buf->length = crypt_secret.length;
2609 r->out.old_val->buf->data = crypt_secret.data;
2613 if (r->in.old_mtime) {
2614 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2615 if (!r->out.old_mtime) {
2616 return NT_STATUS_NO_MEMORY;
2618 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
2621 if (r->in.new_val) {
2622 const struct ldb_val *new_val;
2623 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2624 if (!r->out.new_val) {
2625 return NT_STATUS_NO_MEMORY;
2628 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2630 if (new_val && new_val->length) {
2631 secret.data = new_val->data;
2632 secret.length = new_val->length;
2634 /* Encrypt */
2635 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2636 if (!crypt_secret.length) {
2637 return NT_STATUS_NO_MEMORY;
2639 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2640 if (!r->out.new_val->buf) {
2641 return NT_STATUS_NO_MEMORY;
2643 r->out.new_val->buf->length = crypt_secret.length;
2644 r->out.new_val->buf->size = crypt_secret.length;
2645 r->out.new_val->buf->data = crypt_secret.data;
2649 if (r->in.new_mtime) {
2650 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2651 if (!r->out.new_mtime) {
2652 return NT_STATUS_NO_MEMORY;
2654 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2657 return NT_STATUS_OK;
2662 lsa_LookupPrivValue
2664 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
2665 TALLOC_CTX *mem_ctx,
2666 struct lsa_LookupPrivValue *r)
2668 struct dcesrv_handle *h;
2669 struct lsa_policy_state *state;
2670 int id;
2672 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2674 state = h->data;
2676 id = sec_privilege_id(r->in.name->string);
2677 if (id == -1) {
2678 return NT_STATUS_NO_SUCH_PRIVILEGE;
2681 r->out.luid->low = id;
2682 r->out.luid->high = 0;
2684 return NT_STATUS_OK;
2689 lsa_LookupPrivName
2691 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
2692 TALLOC_CTX *mem_ctx,
2693 struct lsa_LookupPrivName *r)
2695 struct dcesrv_handle *h;
2696 struct lsa_policy_state *state;
2697 const char *privname;
2699 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2701 state = h->data;
2703 if (r->in.luid->high != 0) {
2704 return NT_STATUS_NO_SUCH_PRIVILEGE;
2707 privname = sec_privilege_name(r->in.luid->low);
2708 if (privname == NULL) {
2709 return NT_STATUS_NO_SUCH_PRIVILEGE;
2712 r->out.name = talloc(mem_ctx, struct lsa_StringLarge);
2713 if (r->out.name == NULL) {
2714 return NT_STATUS_NO_MEMORY;
2716 r->out.name->string = privname;
2718 return NT_STATUS_OK;
2723 lsa_LookupPrivDisplayName
2725 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
2726 TALLOC_CTX *mem_ctx,
2727 struct lsa_LookupPrivDisplayName *r)
2729 struct dcesrv_handle *h;
2730 struct lsa_policy_state *state;
2731 int id;
2733 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2735 state = h->data;
2737 id = sec_privilege_id(r->in.name->string);
2738 if (id == -1) {
2739 return NT_STATUS_NO_SUCH_PRIVILEGE;
2742 r->out.disp_name = talloc(mem_ctx, struct lsa_StringLarge);
2743 if (r->out.disp_name == NULL) {
2744 return NT_STATUS_NO_MEMORY;
2747 r->out.disp_name->string = sec_privilege_display_name(id, r->in.language_id);
2748 if (r->out.disp_name->string == NULL) {
2749 return NT_STATUS_INTERNAL_ERROR;
2752 return NT_STATUS_OK;
2757 lsa_EnumAccountsWithUserRight
2759 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
2760 TALLOC_CTX *mem_ctx,
2761 struct lsa_EnumAccountsWithUserRight *r)
2763 struct dcesrv_handle *h;
2764 struct lsa_policy_state *state;
2765 int ret, i;
2766 struct ldb_message **res;
2767 const char * const attrs[] = { "objectSid", NULL};
2768 const char *privname;
2770 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2772 state = h->data;
2774 if (r->in.name == NULL) {
2775 return NT_STATUS_NO_SUCH_PRIVILEGE;
2778 privname = r->in.name->string;
2779 if (sec_privilege_id(privname) == -1) {
2780 return NT_STATUS_NO_SUCH_PRIVILEGE;
2783 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
2784 "privilege=%s", privname);
2785 if (ret == -1) {
2786 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2788 if (ret == 0) {
2789 return NT_STATUS_NO_MORE_ENTRIES;
2792 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2793 if (r->out.sids->sids == NULL) {
2794 return NT_STATUS_NO_MEMORY;
2796 for (i=0;i<ret;i++) {
2797 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2798 res[i], "objectSid");
2799 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2801 r->out.sids->num_sids = ret;
2803 return NT_STATUS_OK;
2808 lsa_AddAccountRights
2810 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
2811 TALLOC_CTX *mem_ctx,
2812 struct lsa_AddAccountRights *r)
2814 struct dcesrv_handle *h;
2815 struct lsa_policy_state *state;
2817 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2819 state = h->data;
2821 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2822 LDB_FLAG_MOD_ADD,
2823 r->in.sid, r->in.rights);
2828 lsa_RemoveAccountRights
2830 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
2831 TALLOC_CTX *mem_ctx,
2832 struct lsa_RemoveAccountRights *r)
2834 struct dcesrv_handle *h;
2835 struct lsa_policy_state *state;
2837 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2839 state = h->data;
2841 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2842 LDB_FLAG_MOD_DELETE,
2843 r->in.sid, r->in.rights);
2848 lsa_StorePrivateData
2850 static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2851 struct lsa_StorePrivateData *r)
2853 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2858 lsa_RetrievePrivateData
2860 static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2861 struct lsa_RetrievePrivateData *r)
2863 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2868 lsa_GetUserName
2870 static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2871 struct lsa_GetUserName *r)
2873 NTSTATUS status = NT_STATUS_OK;
2874 const char *account_name;
2875 const char *authority_name;
2876 struct lsa_String *_account_name;
2877 struct lsa_StringPointer *_authority_name = NULL;
2879 /* this is what w2k3 does */
2880 r->out.account_name = r->in.account_name;
2881 r->out.authority_name = r->in.authority_name;
2883 if (r->in.account_name && r->in.account_name->string) {
2884 return NT_STATUS_INVALID_PARAMETER;
2887 if (r->in.authority_name &&
2888 r->in.authority_name->string &&
2889 r->in.authority_name->string->string) {
2890 return NT_STATUS_INVALID_PARAMETER;
2893 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
2894 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
2896 _account_name = talloc(mem_ctx, struct lsa_String);
2897 NT_STATUS_HAVE_NO_MEMORY(_account_name);
2898 _account_name->string = account_name;
2900 if (r->in.authority_name) {
2901 _authority_name = talloc(mem_ctx, struct lsa_StringPointer);
2902 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
2903 _authority_name->string = talloc(mem_ctx, struct lsa_String);
2904 NT_STATUS_HAVE_NO_MEMORY(_authority_name->string);
2905 _authority_name->string->string = authority_name;
2908 r->out.account_name = _account_name;
2909 r->out.authority_name = _authority_name;
2911 return status;
2915 lsa_SetInfoPolicy2
2917 static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
2918 TALLOC_CTX *mem_ctx,
2919 struct lsa_SetInfoPolicy2 *r)
2921 /* need to support these */
2922 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2926 lsa_QueryDomainInformationPolicy
2928 static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2929 TALLOC_CTX *mem_ctx,
2930 struct lsa_QueryDomainInformationPolicy *r)
2932 r->out.info = talloc(mem_ctx, union lsa_DomainInformationPolicy);
2933 if (!r->out.info) {
2934 return NT_STATUS_NO_MEMORY;
2937 switch (r->in.level) {
2938 case LSA_DOMAIN_INFO_POLICY_EFS:
2939 talloc_free(r->out.info);
2940 r->out.info = NULL;
2941 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2942 case LSA_DOMAIN_INFO_POLICY_KERBEROS:
2944 struct lsa_DomainInfoKerberos *k = &r->out.info->kerberos_info;
2945 struct smb_krb5_context *smb_krb5_context;
2946 int ret = smb_krb5_init_context(mem_ctx,
2947 dce_call->event_ctx,
2948 dce_call->conn->dce_ctx->lp_ctx,
2949 &smb_krb5_context);
2950 if (ret != 0) {
2951 talloc_free(r->out.info);
2952 r->out.info = NULL;
2953 return NT_STATUS_INTERNAL_ERROR;
2955 k->enforce_restrictions = 0; /* FIXME, details missing from MS-LSAD 2.2.53 */
2956 k->service_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
2957 k->user_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
2958 k->user_tkt_renewaltime = 0; /* Need to find somewhere to store this, and query in KDC too */
2959 k->clock_skew = krb5_get_max_time_skew(smb_krb5_context->krb5_context);
2960 talloc_free(smb_krb5_context);
2961 return NT_STATUS_OK;
2963 default:
2964 talloc_free(r->out.info);
2965 r->out.info = NULL;
2966 return NT_STATUS_INVALID_INFO_CLASS;
2971 lsa_SetDomInfoPolicy
2973 static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2974 TALLOC_CTX *mem_ctx,
2975 struct lsa_SetDomainInformationPolicy *r)
2977 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2981 lsa_TestCall
2983 static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
2984 TALLOC_CTX *mem_ctx,
2985 struct lsa_TestCall *r)
2987 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2991 lsa_CREDRWRITE
2993 static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2994 struct lsa_CREDRWRITE *r)
2996 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3001 lsa_CREDRREAD
3003 static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3004 struct lsa_CREDRREAD *r)
3006 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3011 lsa_CREDRENUMERATE
3013 static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3014 struct lsa_CREDRENUMERATE *r)
3016 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3021 lsa_CREDRWRITEDOMAINCREDENTIALS
3023 static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3024 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3026 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3031 lsa_CREDRREADDOMAINCREDENTIALS
3033 static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3034 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3036 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3041 lsa_CREDRDELETE
3043 static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3044 struct lsa_CREDRDELETE *r)
3046 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3051 lsa_CREDRGETTARGETINFO
3053 static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3054 struct lsa_CREDRGETTARGETINFO *r)
3056 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3061 lsa_CREDRPROFILELOADED
3063 static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3064 struct lsa_CREDRPROFILELOADED *r)
3066 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3071 lsa_CREDRGETSESSIONTYPES
3073 static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3074 struct lsa_CREDRGETSESSIONTYPES *r)
3076 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3081 lsa_LSARREGISTERAUDITEVENT
3083 static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3084 struct lsa_LSARREGISTERAUDITEVENT *r)
3086 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3091 lsa_LSARGENAUDITEVENT
3093 static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3094 struct lsa_LSARGENAUDITEVENT *r)
3096 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3101 lsa_LSARUNREGISTERAUDITEVENT
3103 static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3104 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3106 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3111 lsa_lsaRQueryForestTrustInformation
3113 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3114 struct lsa_lsaRQueryForestTrustInformation *r)
3116 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3121 lsa_LSARSETFORESTTRUSTINFORMATION
3123 static NTSTATUS dcesrv_lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3124 struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
3126 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3131 lsa_CREDRRENAME
3133 static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3134 struct lsa_CREDRRENAME *r)
3136 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3142 lsa_LSAROPENPOLICYSCE
3144 static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3145 struct lsa_LSAROPENPOLICYSCE *r)
3147 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3152 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
3154 static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3155 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
3157 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3162 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
3164 static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3165 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
3167 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3172 lsa_LSARADTREPORTSECURITYEVENT
3174 static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3175 struct lsa_LSARADTREPORTSECURITYEVENT *r)
3177 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3181 /* include the generated boilerplate */
3182 #include "librpc/gen_ndr/ndr_lsa_s.c"
3186 /*****************************************
3187 NOTE! The remaining calls below were
3188 removed in w2k3, so the DCESRV_FAULT()
3189 replies are the correct implementation. Do
3190 not try and fill these in with anything else
3191 ******************************************/
3194 dssetup_DsRoleDnsNameToFlatName
3196 static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3197 struct dssetup_DsRoleDnsNameToFlatName *r)
3199 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3204 dssetup_DsRoleDcAsDc
3206 static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3207 struct dssetup_DsRoleDcAsDc *r)
3209 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3214 dssetup_DsRoleDcAsReplica
3216 static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3217 struct dssetup_DsRoleDcAsReplica *r)
3219 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3224 dssetup_DsRoleDemoteDc
3226 static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3227 struct dssetup_DsRoleDemoteDc *r)
3229 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3234 dssetup_DsRoleGetDcOperationProgress
3236 static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3237 struct dssetup_DsRoleGetDcOperationProgress *r)
3239 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3244 dssetup_DsRoleGetDcOperationResults
3246 static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3247 struct dssetup_DsRoleGetDcOperationResults *r)
3249 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3254 dssetup_DsRoleCancel
3256 static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3257 struct dssetup_DsRoleCancel *r)
3259 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3264 dssetup_DsRoleServerSaveStateForUpgrade
3266 static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3267 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
3269 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3274 dssetup_DsRoleUpgradeDownlevelServer
3276 static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3277 struct dssetup_DsRoleUpgradeDownlevelServer *r)
3279 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3284 dssetup_DsRoleAbortDownlevelServerUpgrade
3286 static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3287 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
3289 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3293 /* include the generated boilerplate */
3294 #include "librpc/gen_ndr/ndr_dssetup_s.c"
3296 NTSTATUS dcerpc_server_lsa_init(void)
3298 NTSTATUS ret;
3300 ret = dcerpc_server_dssetup_init();
3301 if (!NT_STATUS_IS_OK(ret)) {
3302 return ret;
3304 ret = dcerpc_server_lsarpc_init();
3305 if (!NT_STATUS_IS_OK(ret)) {
3306 return ret;
3308 return ret;