Fix Coverity ID 628, Andrew B., please check!
[Samba/gbeck.git] / source4 / rpc_server / lsa / dcesrv_lsa.c
blobcbadf654fbdadceac3bb49322baa8312f5dc5bbc
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_user == 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 opn;
1264 struct lsa_DeleteObject del;
1265 struct dcesrv_handle *h;
1267 opn.in.handle = r->in.handle;
1268 opn.in.sid = r->in.dom_sid;
1269 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1270 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1271 if (!opn.out.trustdom_handle) {
1272 return NT_STATUS_NO_MEMORY;
1274 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
1275 if (!NT_STATUS_IS_OK(status)) {
1276 return status;
1279 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
1280 talloc_steal(mem_ctx, h);
1282 del.in.handle = opn.out.trustdom_handle;
1283 del.out.handle = opn.out.trustdom_handle;
1284 status = dcesrv_lsa_DeleteObject(dce_call, mem_ctx, &del);
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 opn;
1411 struct lsa_QueryTrustedDomainInfo query;
1412 struct dcesrv_handle *h;
1414 opn.in.handle = r->in.handle;
1415 opn.in.sid = r->in.dom_sid;
1416 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1417 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1418 if (!opn.out.trustdom_handle) {
1419 return NT_STATUS_NO_MEMORY;
1421 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
1422 if (!NT_STATUS_IS_OK(status)) {
1423 return status;
1426 /* Ensure this handle goes away at the end of this call */
1427 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
1428 talloc_steal(mem_ctx, h);
1430 query.in.trustdom_handle = opn.out.trustdom_handle;
1431 query.in.level = r->in.level;
1432 query.out.info = r->out.info;
1433 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1434 if (!NT_STATUS_IS_OK(status)) {
1435 return status;
1438 return NT_STATUS_OK;
1442 lsa_SetTrustedDomainInfoByName
1444 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1445 TALLOC_CTX *mem_ctx,
1446 struct lsa_SetTrustedDomainInfoByName *r)
1448 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1452 lsa_QueryTrustedDomainInfoByName
1454 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1455 TALLOC_CTX *mem_ctx,
1456 struct lsa_QueryTrustedDomainInfoByName *r)
1458 NTSTATUS status;
1459 struct lsa_OpenTrustedDomainByName opn;
1460 struct lsa_QueryTrustedDomainInfo query;
1461 struct dcesrv_handle *h;
1463 opn.in.handle = r->in.handle;
1464 opn.in.name = *r->in.trusted_domain;
1465 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1466 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1467 if (!opn.out.trustdom_handle) {
1468 return NT_STATUS_NO_MEMORY;
1470 status = dcesrv_lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &opn);
1471 if (!NT_STATUS_IS_OK(status)) {
1472 return status;
1475 /* Ensure this handle goes away at the end of this call */
1476 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
1477 talloc_steal(mem_ctx, h);
1479 query.in.trustdom_handle = opn.out.trustdom_handle;
1480 query.in.level = r->in.level;
1481 query.out.info = r->out.info;
1482 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1483 if (!NT_STATUS_IS_OK(status)) {
1484 return status;
1487 return NT_STATUS_OK;
1491 lsa_CloseTrustedDomainEx
1493 static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
1494 TALLOC_CTX *mem_ctx,
1495 struct lsa_CloseTrustedDomainEx *r)
1497 /* The result of a bad hair day from an IDL programmer? Not
1498 * implmented in Win2k3. You should always just lsa_Close
1499 * anyway. */
1500 return NT_STATUS_NOT_IMPLEMENTED;
1505 comparison function for sorting lsa_DomainInformation array
1507 static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
1509 return strcasecmp_m(e1->name.string, e2->name.string);
1513 lsa_EnumTrustDom
1515 static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1516 struct lsa_EnumTrustDom *r)
1518 struct dcesrv_handle *policy_handle;
1519 struct lsa_DomainInfo *entries;
1520 struct lsa_policy_state *policy_state;
1521 struct ldb_message **domains;
1522 const char *attrs[] = {
1523 "flatname",
1524 "securityIdentifier",
1525 NULL
1529 int count, i;
1531 *r->out.resume_handle = 0;
1533 r->out.domains->domains = NULL;
1534 r->out.domains->count = 0;
1536 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1538 policy_state = policy_handle->data;
1540 /* search for all users in this domain. This could possibly be cached and
1541 resumed based on resume_key */
1542 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1543 "objectclass=trustedDomain");
1544 if (count == -1) {
1545 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1548 /* convert to lsa_TrustInformation format */
1549 entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
1550 if (!entries) {
1551 return NT_STATUS_NO_MEMORY;
1553 for (i=0;i<count;i++) {
1554 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
1555 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
1558 /* sort the results by name */
1559 qsort(entries, count, sizeof(*entries),
1560 (comparison_fn_t)compare_DomainInfo);
1562 if (*r->in.resume_handle >= count) {
1563 *r->out.resume_handle = -1;
1565 return NT_STATUS_NO_MORE_ENTRIES;
1568 /* return the rest, limit by max_size. Note that we
1569 use the w2k3 element size value of 60 */
1570 r->out.domains->count = count - *r->in.resume_handle;
1571 r->out.domains->count = MIN(r->out.domains->count,
1572 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
1574 r->out.domains->domains = entries + *r->in.resume_handle;
1575 r->out.domains->count = r->out.domains->count;
1577 if (r->out.domains->count < count - *r->in.resume_handle) {
1578 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1579 return STATUS_MORE_ENTRIES;
1582 return NT_STATUS_OK;
1586 comparison function for sorting lsa_DomainInformation array
1588 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
1590 return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
1594 lsa_EnumTrustedDomainsEx
1596 static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1597 struct lsa_EnumTrustedDomainsEx *r)
1599 struct dcesrv_handle *policy_handle;
1600 struct lsa_TrustDomainInfoInfoEx *entries;
1601 struct lsa_policy_state *policy_state;
1602 struct ldb_message **domains;
1603 const char *attrs[] = {
1604 "flatname",
1605 "trustPartner",
1606 "securityIdentifier",
1607 "trustDirection",
1608 "trustType",
1609 "trustAttributes",
1610 NULL
1612 NTSTATUS nt_status;
1614 int count, i;
1616 *r->out.resume_handle = 0;
1618 r->out.domains->domains = NULL;
1619 r->out.domains->count = 0;
1621 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1623 policy_state = policy_handle->data;
1625 /* search for all users in this domain. This could possibly be cached and
1626 resumed based on resume_key */
1627 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1628 "objectclass=trustedDomain");
1629 if (count == -1) {
1630 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1633 /* convert to lsa_DomainInformation format */
1634 entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
1635 if (!entries) {
1636 return NT_STATUS_NO_MEMORY;
1638 for (i=0;i<count;i++) {
1639 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
1640 if (!NT_STATUS_IS_OK(nt_status)) {
1641 return nt_status;
1645 /* sort the results by name */
1646 qsort(entries, count, sizeof(*entries),
1647 (comparison_fn_t)compare_TrustDomainInfoInfoEx);
1649 if (*r->in.resume_handle >= count) {
1650 *r->out.resume_handle = -1;
1652 return NT_STATUS_NO_MORE_ENTRIES;
1655 /* return the rest, limit by max_size. Note that we
1656 use the w2k3 element size value of 60 */
1657 r->out.domains->count = count - *r->in.resume_handle;
1658 r->out.domains->count = MIN(r->out.domains->count,
1659 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
1661 r->out.domains->domains = entries + *r->in.resume_handle;
1662 r->out.domains->count = r->out.domains->count;
1664 if (r->out.domains->count < count - *r->in.resume_handle) {
1665 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1666 return STATUS_MORE_ENTRIES;
1669 return NT_STATUS_OK;
1674 lsa_OpenAccount
1676 static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1677 struct lsa_OpenAccount *r)
1679 struct dcesrv_handle *h, *ah;
1680 struct lsa_policy_state *state;
1681 struct lsa_account_state *astate;
1683 ZERO_STRUCTP(r->out.acct_handle);
1685 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1687 state = h->data;
1689 astate = talloc(dce_call->conn, struct lsa_account_state);
1690 if (astate == NULL) {
1691 return NT_STATUS_NO_MEMORY;
1694 astate->account_sid = dom_sid_dup(astate, r->in.sid);
1695 if (astate->account_sid == NULL) {
1696 talloc_free(astate);
1697 return NT_STATUS_NO_MEMORY;
1700 astate->policy = talloc_reference(astate, state);
1701 astate->access_mask = r->in.access_mask;
1703 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
1704 if (!ah) {
1705 talloc_free(astate);
1706 return NT_STATUS_NO_MEMORY;
1709 ah->data = talloc_steal(ah, astate);
1711 *r->out.acct_handle = ah->wire_handle;
1713 return NT_STATUS_OK;
1718 lsa_EnumPrivsAccount
1720 static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
1721 TALLOC_CTX *mem_ctx,
1722 struct lsa_EnumPrivsAccount *r)
1724 struct dcesrv_handle *h;
1725 struct lsa_account_state *astate;
1726 int ret, i;
1727 struct ldb_message **res;
1728 const char * const attrs[] = { "privilege", NULL};
1729 struct ldb_message_element *el;
1730 const char *sidstr;
1731 struct lsa_PrivilegeSet *privs;
1733 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1735 astate = h->data;
1737 privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
1738 if (privs == NULL) {
1739 return NT_STATUS_NO_MEMORY;
1741 privs->count = 0;
1742 privs->unknown = 0;
1743 privs->set = NULL;
1745 *r->out.privs = privs;
1747 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
1748 if (sidstr == NULL) {
1749 return NT_STATUS_NO_MEMORY;
1752 ret = gendb_search(astate->policy->sam_ldb, mem_ctx, NULL, &res, attrs,
1753 "objectSid=%s", sidstr);
1754 if (ret != 1) {
1755 return NT_STATUS_OK;
1758 el = ldb_msg_find_element(res[0], "privilege");
1759 if (el == NULL || el->num_values == 0) {
1760 return NT_STATUS_OK;
1763 privs->set = talloc_array(privs,
1764 struct lsa_LUIDAttribute, el->num_values);
1765 if (privs->set == NULL) {
1766 return NT_STATUS_NO_MEMORY;
1769 for (i=0;i<el->num_values;i++) {
1770 int id = sec_privilege_id((const char *)el->values[i].data);
1771 if (id == -1) {
1772 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1774 privs->set[i].attribute = 0;
1775 privs->set[i].luid.low = id;
1776 privs->set[i].luid.high = 0;
1779 privs->count = el->num_values;
1781 return NT_STATUS_OK;
1785 lsa_EnumAccountRights
1787 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
1788 TALLOC_CTX *mem_ctx,
1789 struct lsa_EnumAccountRights *r)
1791 struct dcesrv_handle *h;
1792 struct lsa_policy_state *state;
1793 int ret, i;
1794 struct ldb_message **res;
1795 const char * const attrs[] = { "privilege", NULL};
1796 const char *sidstr;
1797 struct ldb_message_element *el;
1799 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1801 state = h->data;
1803 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
1804 if (sidstr == NULL) {
1805 return NT_STATUS_NO_MEMORY;
1808 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
1809 "(&(objectSid=%s)(privilege=*))", sidstr);
1810 if (ret == 0) {
1811 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1813 if (ret > 1) {
1814 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1816 if (ret == -1) {
1817 DEBUG(3, ("searching for account rights for SID: %s failed: %s",
1818 dom_sid_string(mem_ctx, r->in.sid),
1819 ldb_errstring(state->sam_ldb)));
1820 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1823 el = ldb_msg_find_element(res[0], "privilege");
1824 if (el == NULL || el->num_values == 0) {
1825 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1828 r->out.rights->count = el->num_values;
1829 r->out.rights->names = talloc_array(r->out.rights,
1830 struct lsa_StringLarge, r->out.rights->count);
1831 if (r->out.rights->names == NULL) {
1832 return NT_STATUS_NO_MEMORY;
1835 for (i=0;i<el->num_values;i++) {
1836 r->out.rights->names[i].string = (const char *)el->values[i].data;
1839 return NT_STATUS_OK;
1845 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
1847 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
1848 TALLOC_CTX *mem_ctx,
1849 struct lsa_policy_state *state,
1850 int ldb_flag,
1851 struct dom_sid *sid,
1852 const struct lsa_RightSet *rights)
1854 const char *sidstr;
1855 struct ldb_message *msg;
1856 struct ldb_message_element *el;
1857 int i, ret;
1858 struct lsa_EnumAccountRights r2;
1860 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, sid);
1861 if (sidstr == NULL) {
1862 return NT_STATUS_NO_MEMORY;
1865 msg = ldb_msg_new(mem_ctx);
1866 if (msg == NULL) {
1867 return NT_STATUS_NO_MEMORY;
1870 msg->dn = samdb_search_dn(state->sam_ldb, mem_ctx,
1871 NULL, "objectSid=%s", sidstr);
1872 if (msg->dn == NULL) {
1873 NTSTATUS status;
1874 if (ldb_flag == LDB_FLAG_MOD_DELETE) {
1875 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1877 status = samdb_create_foreign_security_principal(state->sam_ldb, mem_ctx,
1878 sid, &msg->dn);
1879 if (!NT_STATUS_IS_OK(status)) {
1880 return status;
1882 return NT_STATUS_NO_SUCH_USER;
1885 if (ldb_msg_add_empty(msg, "privilege", ldb_flag, NULL)) {
1886 return NT_STATUS_NO_MEMORY;
1889 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1890 NTSTATUS status;
1892 r2.in.handle = &state->handle->wire_handle;
1893 r2.in.sid = sid;
1894 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
1896 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1897 if (!NT_STATUS_IS_OK(status)) {
1898 ZERO_STRUCTP(r2.out.rights);
1902 for (i=0;i<rights->count;i++) {
1903 if (sec_privilege_id(rights->names[i].string) == -1) {
1904 return NT_STATUS_NO_SUCH_PRIVILEGE;
1907 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1908 int j;
1909 for (j=0;j<r2.out.rights->count;j++) {
1910 if (strcasecmp_m(r2.out.rights->names[j].string,
1911 rights->names[i].string) == 0) {
1912 break;
1915 if (j != r2.out.rights->count) continue;
1918 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
1919 if (ret != LDB_SUCCESS) {
1920 return NT_STATUS_NO_MEMORY;
1924 el = ldb_msg_find_element(msg, "privilege");
1925 if (!el) {
1926 return NT_STATUS_OK;
1929 ret = ldb_modify(state->sam_ldb, msg);
1930 if (ret != 0) {
1931 if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1932 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1934 DEBUG(3, ("Could not %s attributes from %s: %s",
1935 ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add",
1936 ldb_dn_get_linearized(msg->dn), ldb_errstring(state->sam_ldb)));
1937 return NT_STATUS_UNEXPECTED_IO_ERROR;
1940 return NT_STATUS_OK;
1944 lsa_AddPrivilegesToAccount
1946 static NTSTATUS dcesrv_lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1947 struct lsa_AddPrivilegesToAccount *r)
1949 struct lsa_RightSet rights;
1950 struct dcesrv_handle *h;
1951 struct lsa_account_state *astate;
1952 int i;
1954 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1956 astate = h->data;
1958 rights.count = r->in.privs->count;
1959 rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
1960 if (rights.names == NULL) {
1961 return NT_STATUS_NO_MEMORY;
1963 for (i=0;i<rights.count;i++) {
1964 int id = r->in.privs->set[i].luid.low;
1965 if (r->in.privs->set[i].luid.high) {
1966 return NT_STATUS_NO_SUCH_PRIVILEGE;
1968 rights.names[i].string = sec_privilege_name(id);
1969 if (rights.names[i].string == NULL) {
1970 return NT_STATUS_NO_SUCH_PRIVILEGE;
1974 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1975 LDB_FLAG_MOD_ADD, astate->account_sid,
1976 &rights);
1981 lsa_RemovePrivilegesFromAccount
1983 static NTSTATUS dcesrv_lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1984 struct lsa_RemovePrivilegesFromAccount *r)
1986 struct lsa_RightSet *rights;
1987 struct dcesrv_handle *h;
1988 struct lsa_account_state *astate;
1989 int i;
1991 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1993 astate = h->data;
1995 rights = talloc(mem_ctx, struct lsa_RightSet);
1997 if (r->in.remove_all == 1 &&
1998 r->in.privs == NULL) {
1999 struct lsa_EnumAccountRights r2;
2000 NTSTATUS status;
2002 r2.in.handle = &astate->policy->handle->wire_handle;
2003 r2.in.sid = astate->account_sid;
2004 r2.out.rights = rights;
2006 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
2007 if (!NT_STATUS_IS_OK(status)) {
2008 return status;
2011 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2012 LDB_FLAG_MOD_DELETE, astate->account_sid,
2013 r2.out.rights);
2016 if (r->in.remove_all != 0) {
2017 return NT_STATUS_INVALID_PARAMETER;
2020 rights->count = r->in.privs->count;
2021 rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
2022 if (rights->names == NULL) {
2023 return NT_STATUS_NO_MEMORY;
2025 for (i=0;i<rights->count;i++) {
2026 int id = r->in.privs->set[i].luid.low;
2027 if (r->in.privs->set[i].luid.high) {
2028 return NT_STATUS_NO_SUCH_PRIVILEGE;
2030 rights->names[i].string = sec_privilege_name(id);
2031 if (rights->names[i].string == NULL) {
2032 return NT_STATUS_NO_SUCH_PRIVILEGE;
2036 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2037 LDB_FLAG_MOD_DELETE, astate->account_sid,
2038 rights);
2043 lsa_GetQuotasForAccount
2045 static NTSTATUS dcesrv_lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2046 struct lsa_GetQuotasForAccount *r)
2048 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2053 lsa_SetQuotasForAccount
2055 static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2056 struct lsa_SetQuotasForAccount *r)
2058 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2063 lsa_GetSystemAccessAccount
2065 static NTSTATUS dcesrv_lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2066 struct lsa_GetSystemAccessAccount *r)
2068 int i;
2069 NTSTATUS status;
2070 struct lsa_EnumPrivsAccount enumPrivs;
2071 struct lsa_PrivilegeSet *privs;
2073 privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
2074 if (!privs) {
2075 return NT_STATUS_NO_MEMORY;
2077 privs->count = 0;
2078 privs->unknown = 0;
2079 privs->set = NULL;
2081 enumPrivs.in.handle = r->in.handle;
2082 enumPrivs.out.privs = &privs;
2084 status = dcesrv_lsa_EnumPrivsAccount(dce_call, mem_ctx, &enumPrivs);
2085 if (!NT_STATUS_IS_OK(status)) {
2086 return status;
2089 *(r->out.access_mask) = 0x00000000;
2091 for (i = 0; i < privs->count; i++) {
2092 int priv = privs->set[i].luid.low;
2094 switch (priv) {
2095 case SEC_PRIV_INTERACTIVE_LOGON:
2096 *(r->out.access_mask) |= LSA_POLICY_MODE_INTERACTIVE;
2097 break;
2098 case SEC_PRIV_NETWORK_LOGON:
2099 *(r->out.access_mask) |= LSA_POLICY_MODE_NETWORK;
2100 break;
2101 case SEC_PRIV_REMOTE_INTERACTIVE_LOGON:
2102 *(r->out.access_mask) |= LSA_POLICY_MODE_REMOTE_INTERACTIVE;
2103 break;
2107 return NT_STATUS_OK;
2112 lsa_SetSystemAccessAccount
2114 static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2115 struct lsa_SetSystemAccessAccount *r)
2117 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2122 lsa_CreateSecret
2124 static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2125 struct lsa_CreateSecret *r)
2127 struct dcesrv_handle *policy_handle;
2128 struct lsa_policy_state *policy_state;
2129 struct lsa_secret_state *secret_state;
2130 struct dcesrv_handle *handle;
2131 struct ldb_message **msgs, *msg;
2132 const char *errstr;
2133 const char *attrs[] = {
2134 NULL
2137 const char *name;
2139 int ret;
2141 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2142 ZERO_STRUCTP(r->out.sec_handle);
2144 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2146 case SECURITY_SYSTEM:
2147 case SECURITY_ADMINISTRATOR:
2148 break;
2149 default:
2150 /* Users and annonymous are not allowed create secrets */
2151 return NT_STATUS_ACCESS_DENIED;
2154 policy_state = policy_handle->data;
2156 if (!r->in.name.string) {
2157 return NT_STATUS_INVALID_PARAMETER;
2160 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2161 if (!secret_state) {
2162 return NT_STATUS_NO_MEMORY;
2164 secret_state->policy = policy_state;
2166 msg = ldb_msg_new(mem_ctx);
2167 if (msg == NULL) {
2168 return NT_STATUS_NO_MEMORY;
2171 if (strncmp("G$", r->in.name.string, 2) == 0) {
2172 const char *name2;
2173 name = &r->in.name.string[2];
2174 /* 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) */
2175 secret_state->sam_ldb = talloc_reference(secret_state,
2176 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)));
2177 secret_state->global = true;
2179 if (strlen(name) < 1) {
2180 return NT_STATUS_INVALID_PARAMETER;
2183 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
2184 /* search for the secret record */
2185 ret = gendb_search(secret_state->sam_ldb,
2186 mem_ctx, policy_state->system_dn, &msgs, attrs,
2187 "(&(cn=%s)(objectclass=secret))",
2188 name2);
2189 if (ret > 0) {
2190 return NT_STATUS_OBJECT_NAME_COLLISION;
2193 if (ret == -1) {
2194 DEBUG(0,("Failure searching for CN=%s: %s\n",
2195 name2, ldb_errstring(secret_state->sam_ldb)));
2196 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2199 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
2200 if (!name2 || ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
2201 return NT_STATUS_NO_MEMORY;
2204 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
2206 } else {
2207 secret_state->global = false;
2209 name = r->in.name.string;
2210 if (strlen(name) < 1) {
2211 return NT_STATUS_INVALID_PARAMETER;
2214 secret_state->sam_ldb = talloc_reference(secret_state,
2215 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
2216 /* search for the secret record */
2217 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2218 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2219 &msgs, attrs,
2220 "(&(cn=%s)(objectclass=secret))",
2221 ldb_binary_encode_string(mem_ctx, name));
2222 if (ret > 0) {
2223 return NT_STATUS_OBJECT_NAME_COLLISION;
2226 if (ret == -1) {
2227 DEBUG(0,("Failure searching for CN=%s: %s\n",
2228 name, ldb_errstring(secret_state->sam_ldb)));
2229 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2232 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name);
2233 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
2236 /* pull in all the template attributes. Note this is always from the global samdb */
2237 ret = samdb_copy_template(secret_state->policy->sam_ldb, msg,
2238 "secret", &errstr);
2239 if (ret != 0) {
2240 DEBUG(0,("Failed to load TemplateSecret from samdb: %s\n",
2241 errstr));
2242 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2245 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
2247 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
2249 /* create the secret */
2250 ret = ldb_add(secret_state->sam_ldb, msg);
2251 if (ret != 0) {
2252 DEBUG(0,("Failed to create secret record %s: %s\n",
2253 ldb_dn_get_linearized(msg->dn),
2254 ldb_errstring(secret_state->sam_ldb)));
2255 return NT_STATUS_ACCESS_DENIED;
2258 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2259 if (!handle) {
2260 return NT_STATUS_NO_MEMORY;
2263 handle->data = talloc_steal(handle, secret_state);
2265 secret_state->access_mask = r->in.access_mask;
2266 secret_state->policy = talloc_reference(secret_state, policy_state);
2268 *r->out.sec_handle = handle->wire_handle;
2270 return NT_STATUS_OK;
2275 lsa_OpenSecret
2277 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2278 struct lsa_OpenSecret *r)
2280 struct dcesrv_handle *policy_handle;
2282 struct lsa_policy_state *policy_state;
2283 struct lsa_secret_state *secret_state;
2284 struct dcesrv_handle *handle;
2285 struct ldb_message **msgs;
2286 const char *attrs[] = {
2287 NULL
2290 const char *name;
2292 int ret;
2294 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2295 ZERO_STRUCTP(r->out.sec_handle);
2296 policy_state = policy_handle->data;
2298 if (!r->in.name.string) {
2299 return NT_STATUS_INVALID_PARAMETER;
2302 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2304 case SECURITY_SYSTEM:
2305 case SECURITY_ADMINISTRATOR:
2306 break;
2307 default:
2308 /* Users and annonymous are not allowed to access secrets */
2309 return NT_STATUS_ACCESS_DENIED;
2312 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2313 if (!secret_state) {
2314 return NT_STATUS_NO_MEMORY;
2316 secret_state->policy = policy_state;
2318 if (strncmp("G$", r->in.name.string, 2) == 0) {
2319 name = &r->in.name.string[2];
2320 /* 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) */
2321 secret_state->sam_ldb = talloc_reference(secret_state,
2322 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)));
2323 secret_state->global = true;
2325 if (strlen(name) < 1) {
2326 return NT_STATUS_INVALID_PARAMETER;
2329 /* search for the secret record */
2330 ret = gendb_search(secret_state->sam_ldb,
2331 mem_ctx, policy_state->system_dn, &msgs, attrs,
2332 "(&(cn=%s Secret)(objectclass=secret))",
2333 ldb_binary_encode_string(mem_ctx, name));
2334 if (ret == 0) {
2335 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2338 if (ret != 1) {
2339 DEBUG(0,("Found %d records matching DN %s\n", ret,
2340 ldb_dn_get_linearized(policy_state->system_dn)));
2341 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2344 } else {
2345 secret_state->global = false;
2346 secret_state->sam_ldb = talloc_reference(secret_state,
2347 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
2349 name = r->in.name.string;
2350 if (strlen(name) < 1) {
2351 return NT_STATUS_INVALID_PARAMETER;
2354 /* search for the secret record */
2355 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2356 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2357 &msgs, attrs,
2358 "(&(cn=%s)(objectclass=secret))",
2359 ldb_binary_encode_string(mem_ctx, name));
2360 if (ret == 0) {
2361 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2364 if (ret != 1) {
2365 DEBUG(0,("Found %d records matching CN=%s\n",
2366 ret, ldb_binary_encode_string(mem_ctx, name)));
2367 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2371 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
2373 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2374 if (!handle) {
2375 return NT_STATUS_NO_MEMORY;
2378 handle->data = talloc_steal(handle, secret_state);
2380 secret_state->access_mask = r->in.access_mask;
2381 secret_state->policy = talloc_reference(secret_state, policy_state);
2383 *r->out.sec_handle = handle->wire_handle;
2385 return NT_STATUS_OK;
2390 lsa_SetSecret
2392 static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2393 struct lsa_SetSecret *r)
2396 struct dcesrv_handle *h;
2397 struct lsa_secret_state *secret_state;
2398 struct ldb_message *msg;
2399 DATA_BLOB session_key;
2400 DATA_BLOB crypt_secret, secret;
2401 struct ldb_val val;
2402 int ret;
2403 NTSTATUS status = NT_STATUS_OK;
2405 struct timeval now = timeval_current();
2406 NTTIME nt_now = timeval_to_nttime(&now);
2408 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2410 secret_state = h->data;
2412 msg = ldb_msg_new(mem_ctx);
2413 if (msg == NULL) {
2414 return NT_STATUS_NO_MEMORY;
2417 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
2418 if (!msg->dn) {
2419 return NT_STATUS_NO_MEMORY;
2421 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2422 if (!NT_STATUS_IS_OK(status)) {
2423 return status;
2426 if (r->in.old_val) {
2427 /* Decrypt */
2428 crypt_secret.data = r->in.old_val->data;
2429 crypt_secret.length = r->in.old_val->size;
2431 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2432 if (!NT_STATUS_IS_OK(status)) {
2433 return status;
2436 val.data = secret.data;
2437 val.length = secret.length;
2439 /* set value */
2440 if (samdb_msg_add_value(secret_state->sam_ldb,
2441 mem_ctx, msg, "priorValue", &val) != 0) {
2442 return NT_STATUS_NO_MEMORY;
2445 /* set old value mtime */
2446 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2447 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
2448 return NT_STATUS_NO_MEMORY;
2451 } else {
2452 /* If the old value is not set, then migrate the
2453 * current value to the old value */
2454 const struct ldb_val *old_val;
2455 NTTIME last_set_time;
2456 struct ldb_message **res;
2457 const char *attrs[] = {
2458 "currentValue",
2459 "lastSetTime",
2460 NULL
2463 /* search for the secret record */
2464 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
2465 secret_state->secret_dn, &res, attrs);
2466 if (ret == 0) {
2467 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2470 if (ret != 1) {
2471 DEBUG(0,("Found %d records matching dn=%s\n", ret,
2472 ldb_dn_get_linearized(secret_state->secret_dn)));
2473 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2476 old_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2477 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2479 if (old_val) {
2480 /* set old value */
2481 if (samdb_msg_add_value(secret_state->sam_ldb,
2482 mem_ctx, msg, "priorValue",
2483 old_val) != 0) {
2484 return NT_STATUS_NO_MEMORY;
2486 } else {
2487 if (samdb_msg_add_delete(secret_state->sam_ldb,
2488 mem_ctx, msg, "priorValue")) {
2489 return NT_STATUS_NO_MEMORY;
2494 /* set old value mtime */
2495 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2496 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2497 mem_ctx, msg, "priorSetTime", last_set_time) != 0) {
2498 return NT_STATUS_NO_MEMORY;
2500 } else {
2501 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2502 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
2503 return NT_STATUS_NO_MEMORY;
2508 if (r->in.new_val) {
2509 /* Decrypt */
2510 crypt_secret.data = r->in.new_val->data;
2511 crypt_secret.length = r->in.new_val->size;
2513 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2514 if (!NT_STATUS_IS_OK(status)) {
2515 return status;
2518 val.data = secret.data;
2519 val.length = secret.length;
2521 /* set value */
2522 if (samdb_msg_add_value(secret_state->sam_ldb,
2523 mem_ctx, msg, "currentValue", &val) != 0) {
2524 return NT_STATUS_NO_MEMORY;
2527 /* set new value mtime */
2528 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2529 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2530 return NT_STATUS_NO_MEMORY;
2533 } else {
2534 /* NULL out the NEW value */
2535 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2536 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2537 return NT_STATUS_NO_MEMORY;
2539 if (samdb_msg_add_delete(secret_state->sam_ldb,
2540 mem_ctx, msg, "currentValue")) {
2541 return NT_STATUS_NO_MEMORY;
2545 /* modify the samdb record */
2546 ret = samdb_replace(secret_state->sam_ldb, mem_ctx, msg);
2547 if (ret != 0) {
2548 /* we really need samdb.c to return NTSTATUS */
2549 return NT_STATUS_UNSUCCESSFUL;
2552 return NT_STATUS_OK;
2557 lsa_QuerySecret
2559 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2560 struct lsa_QuerySecret *r)
2562 struct dcesrv_handle *h;
2563 struct lsa_secret_state *secret_state;
2564 struct ldb_message *msg;
2565 DATA_BLOB session_key;
2566 DATA_BLOB crypt_secret, secret;
2567 int ret;
2568 struct ldb_message **res;
2569 const char *attrs[] = {
2570 "currentValue",
2571 "priorValue",
2572 "lastSetTime",
2573 "priorSetTime",
2574 NULL
2577 NTSTATUS nt_status;
2579 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2581 /* Ensure user is permitted to read this... */
2582 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2584 case SECURITY_SYSTEM:
2585 case SECURITY_ADMINISTRATOR:
2586 break;
2587 default:
2588 /* Users and annonymous are not allowed to read secrets */
2589 return NT_STATUS_ACCESS_DENIED;
2592 secret_state = h->data;
2594 /* pull all the user attributes */
2595 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2596 secret_state->secret_dn, &res, attrs);
2597 if (ret != 1) {
2598 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2600 msg = res[0];
2602 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2603 if (!NT_STATUS_IS_OK(nt_status)) {
2604 return nt_status;
2607 if (r->in.old_val) {
2608 const struct ldb_val *prior_val;
2609 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2610 if (!r->out.old_val) {
2611 return NT_STATUS_NO_MEMORY;
2613 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
2615 if (prior_val && prior_val->length) {
2616 secret.data = prior_val->data;
2617 secret.length = prior_val->length;
2619 /* Encrypt */
2620 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2621 if (!crypt_secret.length) {
2622 return NT_STATUS_NO_MEMORY;
2624 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2625 if (!r->out.old_val->buf) {
2626 return NT_STATUS_NO_MEMORY;
2628 r->out.old_val->buf->size = crypt_secret.length;
2629 r->out.old_val->buf->length = crypt_secret.length;
2630 r->out.old_val->buf->data = crypt_secret.data;
2634 if (r->in.old_mtime) {
2635 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2636 if (!r->out.old_mtime) {
2637 return NT_STATUS_NO_MEMORY;
2639 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
2642 if (r->in.new_val) {
2643 const struct ldb_val *new_val;
2644 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2645 if (!r->out.new_val) {
2646 return NT_STATUS_NO_MEMORY;
2649 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2651 if (new_val && new_val->length) {
2652 secret.data = new_val->data;
2653 secret.length = new_val->length;
2655 /* Encrypt */
2656 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2657 if (!crypt_secret.length) {
2658 return NT_STATUS_NO_MEMORY;
2660 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2661 if (!r->out.new_val->buf) {
2662 return NT_STATUS_NO_MEMORY;
2664 r->out.new_val->buf->length = crypt_secret.length;
2665 r->out.new_val->buf->size = crypt_secret.length;
2666 r->out.new_val->buf->data = crypt_secret.data;
2670 if (r->in.new_mtime) {
2671 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2672 if (!r->out.new_mtime) {
2673 return NT_STATUS_NO_MEMORY;
2675 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2678 return NT_STATUS_OK;
2683 lsa_LookupPrivValue
2685 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
2686 TALLOC_CTX *mem_ctx,
2687 struct lsa_LookupPrivValue *r)
2689 struct dcesrv_handle *h;
2690 struct lsa_policy_state *state;
2691 int id;
2693 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2695 state = h->data;
2697 id = sec_privilege_id(r->in.name->string);
2698 if (id == -1) {
2699 return NT_STATUS_NO_SUCH_PRIVILEGE;
2702 r->out.luid->low = id;
2703 r->out.luid->high = 0;
2705 return NT_STATUS_OK;
2710 lsa_LookupPrivName
2712 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
2713 TALLOC_CTX *mem_ctx,
2714 struct lsa_LookupPrivName *r)
2716 struct dcesrv_handle *h;
2717 struct lsa_policy_state *state;
2718 struct lsa_StringLarge *name;
2719 const char *privname;
2721 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2723 state = h->data;
2725 if (r->in.luid->high != 0) {
2726 return NT_STATUS_NO_SUCH_PRIVILEGE;
2729 privname = sec_privilege_name(r->in.luid->low);
2730 if (privname == NULL) {
2731 return NT_STATUS_NO_SUCH_PRIVILEGE;
2734 name = talloc(mem_ctx, struct lsa_StringLarge);
2735 if (name == NULL) {
2736 return NT_STATUS_NO_MEMORY;
2739 name->string = privname;
2741 *r->out.name = name;
2743 return NT_STATUS_OK;
2748 lsa_LookupPrivDisplayName
2750 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
2751 TALLOC_CTX *mem_ctx,
2752 struct lsa_LookupPrivDisplayName *r)
2754 struct dcesrv_handle *h;
2755 struct lsa_policy_state *state;
2756 struct lsa_StringLarge *disp_name = NULL;
2757 int id;
2759 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2761 state = h->data;
2763 id = sec_privilege_id(r->in.name->string);
2764 if (id == -1) {
2765 return NT_STATUS_NO_SUCH_PRIVILEGE;
2768 disp_name = talloc(mem_ctx, struct lsa_StringLarge);
2769 if (disp_name == NULL) {
2770 return NT_STATUS_NO_MEMORY;
2773 disp_name->string = sec_privilege_display_name(id, &r->in.language_id);
2774 if (disp_name->string == NULL) {
2775 return NT_STATUS_INTERNAL_ERROR;
2778 *r->out.disp_name = disp_name;
2779 *r->out.returned_language_id = 0;
2781 return NT_STATUS_OK;
2786 lsa_EnumAccountsWithUserRight
2788 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
2789 TALLOC_CTX *mem_ctx,
2790 struct lsa_EnumAccountsWithUserRight *r)
2792 struct dcesrv_handle *h;
2793 struct lsa_policy_state *state;
2794 int ret, i;
2795 struct ldb_message **res;
2796 const char * const attrs[] = { "objectSid", NULL};
2797 const char *privname;
2799 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2801 state = h->data;
2803 if (r->in.name == NULL) {
2804 return NT_STATUS_NO_SUCH_PRIVILEGE;
2807 privname = r->in.name->string;
2808 if (sec_privilege_id(privname) == -1) {
2809 return NT_STATUS_NO_SUCH_PRIVILEGE;
2812 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
2813 "privilege=%s", privname);
2814 if (ret == -1) {
2815 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2817 if (ret == 0) {
2818 return NT_STATUS_NO_MORE_ENTRIES;
2821 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2822 if (r->out.sids->sids == NULL) {
2823 return NT_STATUS_NO_MEMORY;
2825 for (i=0;i<ret;i++) {
2826 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2827 res[i], "objectSid");
2828 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2830 r->out.sids->num_sids = ret;
2832 return NT_STATUS_OK;
2837 lsa_AddAccountRights
2839 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
2840 TALLOC_CTX *mem_ctx,
2841 struct lsa_AddAccountRights *r)
2843 struct dcesrv_handle *h;
2844 struct lsa_policy_state *state;
2846 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2848 state = h->data;
2850 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2851 LDB_FLAG_MOD_ADD,
2852 r->in.sid, r->in.rights);
2857 lsa_RemoveAccountRights
2859 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
2860 TALLOC_CTX *mem_ctx,
2861 struct lsa_RemoveAccountRights *r)
2863 struct dcesrv_handle *h;
2864 struct lsa_policy_state *state;
2866 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2868 state = h->data;
2870 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2871 LDB_FLAG_MOD_DELETE,
2872 r->in.sid, r->in.rights);
2877 lsa_StorePrivateData
2879 static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2880 struct lsa_StorePrivateData *r)
2882 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2887 lsa_RetrievePrivateData
2889 static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2890 struct lsa_RetrievePrivateData *r)
2892 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2897 lsa_GetUserName
2899 static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2900 struct lsa_GetUserName *r)
2902 NTSTATUS status = NT_STATUS_OK;
2903 const char *account_name;
2904 const char *authority_name;
2905 struct lsa_String *_account_name;
2906 struct lsa_String *_authority_name = NULL;
2908 /* this is what w2k3 does */
2909 r->out.account_name = r->in.account_name;
2910 r->out.authority_name = r->in.authority_name;
2912 if (r->in.account_name
2913 && *r->in.account_name
2914 /* && *(*r->in.account_name)->string */
2916 return NT_STATUS_INVALID_PARAMETER;
2919 if (r->in.authority_name
2920 && *r->in.authority_name
2921 /* && *(*r->in.authority_name)->string */
2923 return NT_STATUS_INVALID_PARAMETER;
2926 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
2927 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
2929 _account_name = talloc(mem_ctx, struct lsa_String);
2930 NT_STATUS_HAVE_NO_MEMORY(_account_name);
2931 _account_name->string = account_name;
2933 if (r->in.authority_name) {
2934 _authority_name = talloc(mem_ctx, struct lsa_String);
2935 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
2936 _authority_name->string = authority_name;
2939 *r->out.account_name = _account_name;
2940 if (r->out.authority_name) {
2941 *r->out.authority_name = _authority_name;
2944 return status;
2948 lsa_SetInfoPolicy2
2950 static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
2951 TALLOC_CTX *mem_ctx,
2952 struct lsa_SetInfoPolicy2 *r)
2954 /* need to support these */
2955 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2959 lsa_QueryDomainInformationPolicy
2961 static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2962 TALLOC_CTX *mem_ctx,
2963 struct lsa_QueryDomainInformationPolicy *r)
2965 union lsa_DomainInformationPolicy *info;
2967 info = talloc(r->out.info, union lsa_DomainInformationPolicy);
2968 if (!info) {
2969 return NT_STATUS_NO_MEMORY;
2972 switch (r->in.level) {
2973 case LSA_DOMAIN_INFO_POLICY_EFS:
2974 talloc_free(info);
2975 *r->out.info = NULL;
2976 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2977 case LSA_DOMAIN_INFO_POLICY_KERBEROS:
2979 struct lsa_DomainInfoKerberos *k = &info->kerberos_info;
2980 struct smb_krb5_context *smb_krb5_context;
2981 int ret = smb_krb5_init_context(mem_ctx,
2982 dce_call->event_ctx,
2983 dce_call->conn->dce_ctx->lp_ctx,
2984 &smb_krb5_context);
2985 if (ret != 0) {
2986 talloc_free(info);
2987 *r->out.info = NULL;
2988 return NT_STATUS_INTERNAL_ERROR;
2990 k->enforce_restrictions = 0; /* FIXME, details missing from MS-LSAD 2.2.53 */
2991 k->service_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
2992 k->user_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
2993 k->user_tkt_renewaltime = 0; /* Need to find somewhere to store this, and query in KDC too */
2994 k->clock_skew = krb5_get_max_time_skew(smb_krb5_context->krb5_context);
2995 talloc_free(smb_krb5_context);
2996 *r->out.info = info;
2997 return NT_STATUS_OK;
2999 default:
3000 talloc_free(info);
3001 *r->out.info = NULL;
3002 return NT_STATUS_INVALID_INFO_CLASS;
3007 lsa_SetDomInfoPolicy
3009 static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
3010 TALLOC_CTX *mem_ctx,
3011 struct lsa_SetDomainInformationPolicy *r)
3013 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3017 lsa_TestCall
3019 static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
3020 TALLOC_CTX *mem_ctx,
3021 struct lsa_TestCall *r)
3023 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3027 lsa_CREDRWRITE
3029 static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3030 struct lsa_CREDRWRITE *r)
3032 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3037 lsa_CREDRREAD
3039 static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3040 struct lsa_CREDRREAD *r)
3042 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3047 lsa_CREDRENUMERATE
3049 static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3050 struct lsa_CREDRENUMERATE *r)
3052 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3057 lsa_CREDRWRITEDOMAINCREDENTIALS
3059 static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3060 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3062 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3067 lsa_CREDRREADDOMAINCREDENTIALS
3069 static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3070 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3072 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3077 lsa_CREDRDELETE
3079 static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3080 struct lsa_CREDRDELETE *r)
3082 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3087 lsa_CREDRGETTARGETINFO
3089 static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3090 struct lsa_CREDRGETTARGETINFO *r)
3092 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3097 lsa_CREDRPROFILELOADED
3099 static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3100 struct lsa_CREDRPROFILELOADED *r)
3102 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3107 lsa_CREDRGETSESSIONTYPES
3109 static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3110 struct lsa_CREDRGETSESSIONTYPES *r)
3112 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3117 lsa_LSARREGISTERAUDITEVENT
3119 static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3120 struct lsa_LSARREGISTERAUDITEVENT *r)
3122 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3127 lsa_LSARGENAUDITEVENT
3129 static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3130 struct lsa_LSARGENAUDITEVENT *r)
3132 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3137 lsa_LSARUNREGISTERAUDITEVENT
3139 static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3140 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3142 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3147 lsa_lsaRQueryForestTrustInformation
3149 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3150 struct lsa_lsaRQueryForestTrustInformation *r)
3152 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3157 lsa_LSARSETFORESTTRUSTINFORMATION
3159 static NTSTATUS dcesrv_lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3160 struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
3162 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3167 lsa_CREDRRENAME
3169 static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3170 struct lsa_CREDRRENAME *r)
3172 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3178 lsa_LSAROPENPOLICYSCE
3180 static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3181 struct lsa_LSAROPENPOLICYSCE *r)
3183 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3188 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
3190 static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3191 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
3193 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3198 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
3200 static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3201 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
3203 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3208 lsa_LSARADTREPORTSECURITYEVENT
3210 static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3211 struct lsa_LSARADTREPORTSECURITYEVENT *r)
3213 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3217 /* include the generated boilerplate */
3218 #include "librpc/gen_ndr/ndr_lsa_s.c"
3222 /*****************************************
3223 NOTE! The remaining calls below were
3224 removed in w2k3, so the DCESRV_FAULT()
3225 replies are the correct implementation. Do
3226 not try and fill these in with anything else
3227 ******************************************/
3230 dssetup_DsRoleDnsNameToFlatName
3232 static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3233 struct dssetup_DsRoleDnsNameToFlatName *r)
3235 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3240 dssetup_DsRoleDcAsDc
3242 static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3243 struct dssetup_DsRoleDcAsDc *r)
3245 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3250 dssetup_DsRoleDcAsReplica
3252 static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3253 struct dssetup_DsRoleDcAsReplica *r)
3255 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3260 dssetup_DsRoleDemoteDc
3262 static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3263 struct dssetup_DsRoleDemoteDc *r)
3265 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3270 dssetup_DsRoleGetDcOperationProgress
3272 static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3273 struct dssetup_DsRoleGetDcOperationProgress *r)
3275 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3280 dssetup_DsRoleGetDcOperationResults
3282 static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3283 struct dssetup_DsRoleGetDcOperationResults *r)
3285 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3290 dssetup_DsRoleCancel
3292 static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3293 struct dssetup_DsRoleCancel *r)
3295 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3300 dssetup_DsRoleServerSaveStateForUpgrade
3302 static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3303 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
3305 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3310 dssetup_DsRoleUpgradeDownlevelServer
3312 static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3313 struct dssetup_DsRoleUpgradeDownlevelServer *r)
3315 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3320 dssetup_DsRoleAbortDownlevelServerUpgrade
3322 static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3323 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
3325 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3329 /* include the generated boilerplate */
3330 #include "librpc/gen_ndr/ndr_dssetup_s.c"
3332 NTSTATUS dcerpc_server_lsa_init(void)
3334 NTSTATUS ret;
3336 ret = dcerpc_server_dssetup_init();
3337 if (!NT_STATUS_IS_OK(ret)) {
3338 return ret;
3340 ret = dcerpc_server_lsarpc_init();
3341 if (!NT_STATUS_IS_OK(ret)) {
3342 return ret;
3344 return ret;