2 Unix SMB/CIFS implementation.
4 endpoint server for the lsarpc pipe
6 Copyright (C) Andrew Tridgell 2004
7 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2007
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "rpc_server/lsa/lsa.h"
24 #include "util/util_ldb.h"
25 #include "libcli/ldap/ldap_ndr.h"
28 this type allows us to distinguish handle types
32 state associated with a lsa_OpenAccount() operation
34 struct lsa_account_state {
35 struct lsa_policy_state *policy;
37 struct dom_sid *account_sid;
42 state associated with a lsa_OpenSecret() operation
44 struct lsa_secret_state {
45 struct lsa_policy_state *policy;
47 struct ldb_dn *secret_dn;
48 struct ldb_context *sam_ldb;
53 state associated with a lsa_OpenTrustedDomain() operation
55 struct lsa_trusted_domain_state {
56 struct lsa_policy_state *policy;
58 struct ldb_dn *trusted_domain_dn;
61 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
63 struct lsa_EnumAccountRights *r);
65 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
67 struct lsa_policy_state *state,
70 const struct lsa_RightSet *rights);
75 static NTSTATUS dcesrv_lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
78 struct dcesrv_handle *h;
80 *r->out.handle = *r->in.handle;
82 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
86 ZERO_STRUCTP(r->out.handle);
95 static NTSTATUS dcesrv_lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
98 struct dcesrv_handle *h;
101 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
102 if (h->wire_handle.handle_type == LSA_HANDLE_SECRET) {
103 struct lsa_secret_state *secret_state = h->data;
104 ret = ldb_delete(secret_state->sam_ldb,
105 secret_state->secret_dn);
108 return NT_STATUS_INVALID_HANDLE;
112 } else if (h->wire_handle.handle_type == LSA_HANDLE_TRUSTED_DOMAIN) {
113 struct lsa_trusted_domain_state *trusted_domain_state = h->data;
114 ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
115 trusted_domain_state->trusted_domain_dn);
118 return NT_STATUS_INVALID_HANDLE;
122 } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
123 struct lsa_RightSet *rights;
124 struct lsa_account_state *astate;
125 struct lsa_EnumAccountRights r2;
128 rights = talloc(mem_ctx, struct lsa_RightSet);
130 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
134 r2.in.handle = &astate->policy->handle->wire_handle;
135 r2.in.sid = astate->account_sid;
136 r2.out.rights = rights;
138 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
139 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
143 if (!NT_STATUS_IS_OK(status)) {
147 status = dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
148 LDB_FLAG_MOD_DELETE, astate->account_sid,
150 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
154 if (!NT_STATUS_IS_OK(status)) {
159 return NT_STATUS_INVALID_HANDLE;
166 static NTSTATUS dcesrv_lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
167 struct lsa_EnumPrivs *r)
169 struct dcesrv_handle *h;
170 struct lsa_policy_state *state;
172 const char *privname;
174 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
178 i = *r->in.resume_handle;
181 while ((privname = sec_privilege_name(i)) &&
182 r->out.privs->count < r->in.max_count) {
183 struct lsa_PrivEntry *e;
185 r->out.privs->privs = talloc_realloc(r->out.privs,
187 struct lsa_PrivEntry,
188 r->out.privs->count+1);
189 if (r->out.privs->privs == NULL) {
190 return NT_STATUS_NO_MEMORY;
192 e = &r->out.privs->privs[r->out.privs->count];
195 e->name.string = privname;
196 r->out.privs->count++;
200 *r->out.resume_handle = i;
209 static NTSTATUS dcesrv_lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
210 struct lsa_QuerySecurity *r)
212 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
219 static NTSTATUS dcesrv_lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
220 struct lsa_SetSecObj *r)
222 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
229 static NTSTATUS dcesrv_lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
230 struct lsa_ChangePassword *r)
232 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
236 dssetup_DsRoleGetPrimaryDomainInformation
238 This is not an LSA call, but is the only call left on the DSSETUP
239 pipe (after the pipe was truncated), and needs lsa_get_policy_state
241 static WERROR dcesrv_dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state *dce_call,
243 struct dssetup_DsRoleGetPrimaryDomainInformation *r)
245 union dssetup_DsRoleInfo *info;
247 info = talloc(mem_ctx, union dssetup_DsRoleInfo);
248 W_ERROR_HAVE_NO_MEMORY(info);
250 switch (r->in.level) {
251 case DS_ROLE_BASIC_INFORMATION:
253 enum dssetup_DsRole role = DS_ROLE_STANDALONE_SERVER;
255 const char *domain = NULL;
256 const char *dns_domain = NULL;
257 const char *forest = NULL;
258 struct GUID domain_guid;
259 struct lsa_policy_state *state;
261 NTSTATUS status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
262 if (!NT_STATUS_IS_OK(status)) {
263 return ntstatus_to_werror(status);
266 ZERO_STRUCT(domain_guid);
268 switch (lp_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
269 case ROLE_STANDALONE:
270 role = DS_ROLE_STANDALONE_SERVER;
272 case ROLE_DOMAIN_MEMBER:
273 role = DS_ROLE_MEMBER_SERVER;
275 case ROLE_DOMAIN_CONTROLLER:
276 if (samdb_is_pdc(state->sam_ldb)) {
277 role = DS_ROLE_PRIMARY_DC;
279 role = DS_ROLE_BACKUP_DC;
284 switch (lp_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
285 case ROLE_STANDALONE:
286 domain = talloc_strdup(mem_ctx, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx));
287 W_ERROR_HAVE_NO_MEMORY(domain);
289 case ROLE_DOMAIN_MEMBER:
290 domain = talloc_strdup(mem_ctx, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx));
291 W_ERROR_HAVE_NO_MEMORY(domain);
292 /* TODO: what is with dns_domain and forest and guid? */
294 case ROLE_DOMAIN_CONTROLLER:
295 flags = DS_ROLE_PRIMARY_DS_RUNNING;
297 if (state->mixed_domain == 1) {
298 flags |= DS_ROLE_PRIMARY_DS_MIXED_MODE;
301 domain = state->domain_name;
302 dns_domain = state->domain_dns;
303 forest = state->forest_dns;
305 domain_guid = state->domain_guid;
306 flags |= DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT;
310 info->basic.role = role;
311 info->basic.flags = flags;
312 info->basic.domain = domain;
313 info->basic.dns_domain = dns_domain;
314 info->basic.forest = forest;
315 info->basic.domain_guid = domain_guid;
320 case DS_ROLE_UPGRADE_STATUS:
322 info->upgrade.upgrading = DS_ROLE_NOT_UPGRADING;
323 info->upgrade.previous_role = DS_ROLE_PREVIOUS_UNKNOWN;
328 case DS_ROLE_OP_STATUS:
330 info->opstatus.status = DS_ROLE_OP_IDLE;
336 return WERR_INVALID_PARAM;
339 return WERR_INVALID_PARAM;
344 fill in the AccountDomain info
346 static NTSTATUS dcesrv_lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
347 struct lsa_DomainInfo *info)
349 info->name.string = state->domain_name;
350 info->sid = state->domain_sid;
356 fill in the DNS domain info
358 static NTSTATUS dcesrv_lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
359 struct lsa_DnsDomainInfo *info)
361 info->name.string = state->domain_name;
362 info->sid = state->domain_sid;
363 info->dns_domain.string = state->domain_dns;
364 info->dns_forest.string = state->forest_dns;
365 info->domain_guid = state->domain_guid;
373 static NTSTATUS dcesrv_lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
374 struct lsa_QueryInfoPolicy2 *r)
376 struct lsa_policy_state *state;
377 struct dcesrv_handle *h;
381 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
385 r->out.info = talloc(mem_ctx, union lsa_PolicyInformation);
387 return NT_STATUS_NO_MEMORY;
390 ZERO_STRUCTP(r->out.info);
392 switch (r->in.level) {
393 case LSA_POLICY_INFO_DOMAIN:
394 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
395 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &r->out.info->account_domain);
397 case LSA_POLICY_INFO_DNS:
398 return dcesrv_lsa_info_DNS(state, mem_ctx, &r->out.info->dns);
399 case LSA_POLICY_INFO_DB:
400 case LSA_POLICY_INFO_AUDIT_FULL_SET:
401 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
402 return NT_STATUS_INVALID_PARAMETER;
405 return NT_STATUS_INVALID_INFO_CLASS;
411 static NTSTATUS dcesrv_lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
412 struct lsa_QueryInfoPolicy *r)
414 struct lsa_QueryInfoPolicy2 r2;
417 r2.in.handle = r->in.handle;
418 r2.in.level = r->in.level;
420 status = dcesrv_lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
422 r->out.info = r2.out.info;
430 static NTSTATUS dcesrv_lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
431 struct lsa_SetInfoPolicy *r)
433 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
440 static NTSTATUS dcesrv_lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
441 struct lsa_ClearAuditLog *r)
443 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
450 static NTSTATUS dcesrv_lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
451 struct lsa_CreateAccount *r)
453 struct lsa_account_state *astate;
455 struct lsa_policy_state *state;
456 struct dcesrv_handle *h, *ah;
458 ZERO_STRUCTP(r->out.acct_handle);
460 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
464 astate = talloc(dce_call->conn, struct lsa_account_state);
465 if (astate == NULL) {
466 return NT_STATUS_NO_MEMORY;
469 astate->account_sid = dom_sid_dup(astate, r->in.sid);
470 if (astate->account_sid == NULL) {
472 return NT_STATUS_NO_MEMORY;
475 astate->policy = talloc_reference(astate, state);
476 astate->access_mask = r->in.access_mask;
478 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
481 return NT_STATUS_NO_MEMORY;
484 ah->data = talloc_steal(ah, astate);
486 *r->out.acct_handle = ah->wire_handle;
495 static NTSTATUS dcesrv_lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
496 struct lsa_EnumAccounts *r)
498 struct dcesrv_handle *h;
499 struct lsa_policy_state *state;
501 struct ldb_message **res;
502 const char * const attrs[] = { "objectSid", NULL};
505 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
509 /* NOTE: This call must only return accounts that have at least
512 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
513 "(&(objectSid=*)(privilege=*))");
515 return NT_STATUS_NO_SUCH_USER;
518 if (*r->in.resume_handle >= ret) {
519 return NT_STATUS_NO_MORE_ENTRIES;
522 count = ret - *r->in.resume_handle;
523 if (count > r->in.num_entries) {
524 count = r->in.num_entries;
528 return NT_STATUS_NO_MORE_ENTRIES;
531 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, count);
532 if (r->out.sids->sids == NULL) {
533 return NT_STATUS_NO_MEMORY;
536 for (i=0;i<count;i++) {
537 r->out.sids->sids[i].sid =
538 samdb_result_dom_sid(r->out.sids->sids,
539 res[i + *r->in.resume_handle],
541 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
544 r->out.sids->num_sids = count;
545 *r->out.resume_handle = count + *r->in.resume_handle;
553 lsa_CreateTrustedDomainEx2
555 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
557 struct lsa_CreateTrustedDomainEx2 *r)
559 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
563 lsa_CreateTrustedDomainEx
565 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
567 struct lsa_CreateTrustedDomainEx *r)
569 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
573 lsa_CreateTrustedDomain
575 static NTSTATUS dcesrv_lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
576 struct lsa_CreateTrustedDomain *r)
578 struct dcesrv_handle *policy_handle;
579 struct lsa_policy_state *policy_state;
580 struct lsa_trusted_domain_state *trusted_domain_state;
581 struct dcesrv_handle *handle;
582 struct ldb_message **msgs, *msg;
583 const char *attrs[] = {
589 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
590 ZERO_STRUCTP(r->out.trustdom_handle);
592 policy_state = policy_handle->data;
594 if (!r->in.info->name.string) {
595 return NT_STATUS_INVALID_PARAMETER;
597 name = r->in.info->name.string;
599 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
600 if (!trusted_domain_state) {
601 return NT_STATUS_NO_MEMORY;
603 trusted_domain_state->policy = policy_state;
605 msg = ldb_msg_new(mem_ctx);
607 return NT_STATUS_NO_MEMORY;
610 /* search for the trusted_domain record */
611 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
612 mem_ctx, policy_state->system_dn, &msgs, attrs,
613 "(&(cn=%s)(objectclass=trustedDomain))",
614 ldb_binary_encode_string(mem_ctx, r->in.info->name.string));
616 return NT_STATUS_OBJECT_NAME_COLLISION;
619 if (ret < 0 || ret > 1) {
620 DEBUG(0,("Found %d records matching DN %s\n", ret,
621 ldb_dn_get_linearized(policy_state->system_dn)));
622 return NT_STATUS_INTERNAL_DB_CORRUPTION;
625 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
626 if ( ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name)) {
627 return NT_STATUS_NO_MEMORY;
630 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "flatname", name);
632 if (r->in.info->sid) {
633 const char *sid_string = dom_sid_string(mem_ctx, r->in.info->sid);
635 return NT_STATUS_NO_MEMORY;
638 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "securityIdentifier", sid_string);
641 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "objectClass", "trustedDomain");
643 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
645 /* create the trusted_domain */
646 ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg);
650 case LDB_ERR_ENTRY_ALREADY_EXISTS:
651 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
652 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
653 ldb_dn_get_linearized(msg->dn),
654 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
655 return NT_STATUS_DOMAIN_EXISTS;
656 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
657 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
658 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
659 ldb_dn_get_linearized(msg->dn),
660 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
661 return NT_STATUS_ACCESS_DENIED;
663 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
664 DEBUG(0,("Failed to create user record %s: %s\n",
665 ldb_dn_get_linearized(msg->dn),
666 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
667 return NT_STATUS_INTERNAL_DB_CORRUPTION;
670 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
672 return NT_STATUS_NO_MEMORY;
675 handle->data = talloc_steal(handle, trusted_domain_state);
677 trusted_domain_state->access_mask = r->in.access_mask;
678 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
680 *r->out.trustdom_handle = handle->wire_handle;
686 lsa_OpenTrustedDomain
688 static NTSTATUS dcesrv_lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
689 struct lsa_OpenTrustedDomain *r)
691 struct dcesrv_handle *policy_handle;
693 struct lsa_policy_state *policy_state;
694 struct lsa_trusted_domain_state *trusted_domain_state;
695 struct dcesrv_handle *handle;
696 struct ldb_message **msgs;
697 const char *attrs[] = {
701 const char *sid_string;
704 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
705 ZERO_STRUCTP(r->out.trustdom_handle);
706 policy_state = policy_handle->data;
708 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
709 if (!trusted_domain_state) {
710 return NT_STATUS_NO_MEMORY;
712 trusted_domain_state->policy = policy_state;
714 sid_string = dom_sid_string(mem_ctx, r->in.sid);
716 return NT_STATUS_NO_MEMORY;
719 /* search for the trusted_domain record */
720 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
721 mem_ctx, policy_state->system_dn, &msgs, attrs,
722 "(&(securityIdentifier=%s)(objectclass=trustedDomain))",
725 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
729 DEBUG(0,("Found %d records matching DN %s\n", ret,
730 ldb_dn_get_linearized(policy_state->system_dn)));
731 return NT_STATUS_INTERNAL_DB_CORRUPTION;
734 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
736 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
738 return NT_STATUS_NO_MEMORY;
741 handle->data = talloc_steal(handle, trusted_domain_state);
743 trusted_domain_state->access_mask = r->in.access_mask;
744 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
746 *r->out.trustdom_handle = handle->wire_handle;
753 lsa_OpenTrustedDomainByName
755 static NTSTATUS dcesrv_lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
757 struct lsa_OpenTrustedDomainByName *r)
759 struct dcesrv_handle *policy_handle;
761 struct lsa_policy_state *policy_state;
762 struct lsa_trusted_domain_state *trusted_domain_state;
763 struct dcesrv_handle *handle;
764 struct ldb_message **msgs;
765 const char *attrs[] = {
771 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
772 ZERO_STRUCTP(r->out.trustdom_handle);
773 policy_state = policy_handle->data;
775 if (!r->in.name.string) {
776 return NT_STATUS_INVALID_PARAMETER;
779 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
780 if (!trusted_domain_state) {
781 return NT_STATUS_NO_MEMORY;
783 trusted_domain_state->policy = policy_state;
785 /* search for the trusted_domain record */
786 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
787 mem_ctx, policy_state->system_dn, &msgs, attrs,
788 "(&(flatname=%s)(objectclass=trustedDomain))",
789 ldb_binary_encode_string(mem_ctx, r->in.name.string));
791 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
795 DEBUG(0,("Found %d records matching DN %s\n", ret,
796 ldb_dn_get_linearized(policy_state->system_dn)));
797 return NT_STATUS_INTERNAL_DB_CORRUPTION;
800 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
802 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
804 return NT_STATUS_NO_MEMORY;
807 handle->data = talloc_steal(handle, trusted_domain_state);
809 trusted_domain_state->access_mask = r->in.access_mask;
810 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
812 *r->out.trustdom_handle = handle->wire_handle;
820 lsa_SetTrustedDomainInfo
822 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
823 struct lsa_SetTrustedDomainInfo *r)
825 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
831 lsa_SetInfomrationTrustedDomain
833 static NTSTATUS dcesrv_lsa_SetInformationTrustedDomain(struct dcesrv_call_state *dce_call,
835 struct lsa_SetInformationTrustedDomain *r)
837 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
842 lsa_DeleteTrustedDomain
844 static NTSTATUS dcesrv_lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
845 struct lsa_DeleteTrustedDomain *r)
848 struct lsa_OpenTrustedDomain open;
849 struct lsa_Delete delete;
850 struct dcesrv_handle *h;
852 open.in.handle = r->in.handle;
853 open.in.sid = r->in.dom_sid;
854 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
855 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
856 if (!open.out.trustdom_handle) {
857 return NT_STATUS_NO_MEMORY;
859 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
860 if (!NT_STATUS_IS_OK(status)) {
864 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
865 talloc_steal(mem_ctx, h);
867 delete.in.handle = open.out.trustdom_handle;
868 status = dcesrv_lsa_Delete(dce_call, mem_ctx, &delete);
869 if (!NT_STATUS_IS_OK(status)) {
875 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx,
876 struct ldb_message *msg,
877 struct lsa_TrustDomainInfoInfoEx *info_ex)
879 info_ex->domain_name.string
880 = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
881 info_ex->netbios_name.string
882 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
884 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
885 info_ex->trust_direction
886 = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
888 = ldb_msg_find_attr_as_int(msg, "trustType", 0);
889 info_ex->trust_attributes
890 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);
895 lsa_QueryTrustedDomainInfo
897 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
898 struct lsa_QueryTrustedDomainInfo *r)
900 struct dcesrv_handle *h;
901 struct lsa_trusted_domain_state *trusted_domain_state;
902 struct ldb_message *msg;
904 struct ldb_message **res;
905 const char *attrs[] = {
908 "securityIdentifier",
915 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
917 trusted_domain_state = h->data;
919 /* pull all the user attributes */
920 ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
921 trusted_domain_state->trusted_domain_dn, &res, attrs);
923 return NT_STATUS_INTERNAL_DB_CORRUPTION;
927 r->out.info = talloc(mem_ctx, union lsa_TrustedDomainInfo);
929 return NT_STATUS_NO_MEMORY;
931 switch (r->in.level) {
932 case LSA_TRUSTED_DOMAIN_INFO_NAME:
933 r->out.info->name.netbios_name.string
934 = samdb_result_string(msg, "flatname", NULL);
936 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
937 r->out.info->posix_offset.posix_offset
938 = samdb_result_uint(msg, "posixOffset", 0);
940 #if 0 /* Win2k3 doesn't implement this */
941 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
942 r->out.info->info_basic.netbios_name.string
943 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
944 r->out.info->info_basic.sid
945 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
948 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
949 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->info_ex);
951 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
952 ZERO_STRUCT(r->out.info->full_info);
953 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->full_info.info_ex);
955 case LSA_TRUSTED_DOMAIN_INFO_INFO_ALL:
956 ZERO_STRUCT(r->out.info->info_all);
957 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->info_all.info_ex);
959 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS_INFO:
960 case LSA_TRUSTED_DOMAIN_INFO_11:
961 /* oops, we don't want to return the info after all */
962 talloc_free(r->out.info);
964 return NT_STATUS_INVALID_PARAMETER;
966 /* oops, we don't want to return the info after all */
967 talloc_free(r->out.info);
969 return NT_STATUS_INVALID_INFO_CLASS;
977 lsa_QueryTrustedDomainInfoBySid
979 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
980 struct lsa_QueryTrustedDomainInfoBySid *r)
983 struct lsa_OpenTrustedDomain open;
984 struct lsa_QueryTrustedDomainInfo query;
985 struct dcesrv_handle *h;
986 open.in.handle = r->in.handle;
987 open.in.sid = r->in.dom_sid;
988 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
989 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
990 if (!open.out.trustdom_handle) {
991 return NT_STATUS_NO_MEMORY;
993 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
994 if (!NT_STATUS_IS_OK(status)) {
998 /* Ensure this handle goes away at the end of this call */
999 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1000 talloc_steal(mem_ctx, h);
1002 query.in.trustdom_handle = open.out.trustdom_handle;
1003 query.in.level = r->in.level;
1004 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1005 if (!NT_STATUS_IS_OK(status)) {
1009 r->out.info = query.out.info;
1010 return NT_STATUS_OK;
1014 lsa_SetTrustedDomainInfoByName
1016 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1017 TALLOC_CTX *mem_ctx,
1018 struct lsa_SetTrustedDomainInfoByName *r)
1020 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1024 lsa_QueryTrustedDomainInfoByName
1026 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1027 TALLOC_CTX *mem_ctx,
1028 struct lsa_QueryTrustedDomainInfoByName *r)
1031 struct lsa_OpenTrustedDomainByName open;
1032 struct lsa_QueryTrustedDomainInfo query;
1033 struct dcesrv_handle *h;
1034 open.in.handle = r->in.handle;
1035 open.in.name = r->in.trusted_domain;
1036 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1037 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1038 if (!open.out.trustdom_handle) {
1039 return NT_STATUS_NO_MEMORY;
1041 status = dcesrv_lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &open);
1042 if (!NT_STATUS_IS_OK(status)) {
1046 /* Ensure this handle goes away at the end of this call */
1047 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1048 talloc_steal(mem_ctx, h);
1050 query.in.trustdom_handle = open.out.trustdom_handle;
1051 query.in.level = r->in.level;
1052 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1053 if (!NT_STATUS_IS_OK(status)) {
1057 r->out.info = query.out.info;
1058 return NT_STATUS_OK;
1062 lsa_CloseTrustedDomainEx
1064 static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
1065 TALLOC_CTX *mem_ctx,
1066 struct lsa_CloseTrustedDomainEx *r)
1068 /* The result of a bad hair day from an IDL programmer? Not
1069 * implmented in Win2k3. You should always just lsa_Close
1071 return NT_STATUS_NOT_IMPLEMENTED;
1076 comparison function for sorting lsa_DomainInformation array
1078 static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
1080 return strcasecmp_m(e1->name.string, e2->name.string);
1086 static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1087 struct lsa_EnumTrustDom *r)
1089 struct dcesrv_handle *policy_handle;
1090 struct lsa_DomainInfo *entries;
1091 struct lsa_policy_state *policy_state;
1092 struct ldb_message **domains;
1093 const char *attrs[] = {
1095 "securityIdentifier",
1102 *r->out.resume_handle = 0;
1104 r->out.domains->domains = NULL;
1105 r->out.domains->count = 0;
1107 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1109 policy_state = policy_handle->data;
1111 /* search for all users in this domain. This could possibly be cached and
1112 resumed based on resume_key */
1113 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1114 "objectclass=trustedDomain");
1116 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1118 if (count == 0 || r->in.max_size == 0) {
1119 return NT_STATUS_OK;
1122 /* convert to lsa_TrustInformation format */
1123 entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
1125 return NT_STATUS_NO_MEMORY;
1127 for (i=0;i<count;i++) {
1128 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
1129 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
1132 /* sort the results by name */
1133 qsort(entries, count, sizeof(*entries),
1134 (comparison_fn_t)compare_DomainInfo);
1136 if (*r->in.resume_handle >= count) {
1137 *r->out.resume_handle = -1;
1139 return NT_STATUS_NO_MORE_ENTRIES;
1142 /* return the rest, limit by max_size. Note that we
1143 use the w2k3 element size value of 60 */
1144 r->out.domains->count = count - *r->in.resume_handle;
1145 r->out.domains->count = MIN(r->out.domains->count,
1146 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
1148 r->out.domains->domains = entries + *r->in.resume_handle;
1149 r->out.domains->count = r->out.domains->count;
1151 if (r->out.domains->count < count - *r->in.resume_handle) {
1152 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1153 return STATUS_MORE_ENTRIES;
1156 return NT_STATUS_OK;
1160 comparison function for sorting lsa_DomainInformation array
1162 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
1164 return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
1168 lsa_EnumTrustedDomainsEx
1170 static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1171 struct lsa_EnumTrustedDomainsEx *r)
1173 struct dcesrv_handle *policy_handle;
1174 struct lsa_TrustDomainInfoInfoEx *entries;
1175 struct lsa_policy_state *policy_state;
1176 struct ldb_message **domains;
1177 const char *attrs[] = {
1180 "securityIdentifier",
1190 *r->out.resume_handle = 0;
1192 r->out.domains->domains = NULL;
1193 r->out.domains->count = 0;
1195 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1197 policy_state = policy_handle->data;
1199 /* search for all users in this domain. This could possibly be cached and
1200 resumed based on resume_key */
1201 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1202 "objectclass=trustedDomain");
1204 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1206 if (count == 0 || r->in.max_size == 0) {
1207 return NT_STATUS_OK;
1210 /* convert to lsa_DomainInformation format */
1211 entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
1213 return NT_STATUS_NO_MEMORY;
1215 for (i=0;i<count;i++) {
1216 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
1217 if (!NT_STATUS_IS_OK(nt_status)) {
1222 /* sort the results by name */
1223 qsort(entries, count, sizeof(*entries),
1224 (comparison_fn_t)compare_TrustDomainInfoInfoEx);
1226 if (*r->in.resume_handle >= count) {
1227 *r->out.resume_handle = -1;
1229 return NT_STATUS_NO_MORE_ENTRIES;
1232 /* return the rest, limit by max_size. Note that we
1233 use the w2k3 element size value of 60 */
1234 r->out.domains->count = count - *r->in.resume_handle;
1235 r->out.domains->count = MIN(r->out.domains->count,
1236 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
1238 r->out.domains->domains = entries + *r->in.resume_handle;
1239 r->out.domains->count = r->out.domains->count;
1241 if (r->out.domains->count < count - *r->in.resume_handle) {
1242 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1243 return STATUS_MORE_ENTRIES;
1246 return NT_STATUS_OK;
1253 static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1254 struct lsa_OpenAccount *r)
1256 struct dcesrv_handle *h, *ah;
1257 struct lsa_policy_state *state;
1258 struct lsa_account_state *astate;
1260 ZERO_STRUCTP(r->out.acct_handle);
1262 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1266 astate = talloc(dce_call->conn, struct lsa_account_state);
1267 if (astate == NULL) {
1268 return NT_STATUS_NO_MEMORY;
1271 astate->account_sid = dom_sid_dup(astate, r->in.sid);
1272 if (astate->account_sid == NULL) {
1273 talloc_free(astate);
1274 return NT_STATUS_NO_MEMORY;
1277 astate->policy = talloc_reference(astate, state);
1278 astate->access_mask = r->in.access_mask;
1280 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
1282 talloc_free(astate);
1283 return NT_STATUS_NO_MEMORY;
1286 ah->data = talloc_steal(ah, astate);
1288 *r->out.acct_handle = ah->wire_handle;
1290 return NT_STATUS_OK;
1295 lsa_EnumPrivsAccount
1297 static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
1298 TALLOC_CTX *mem_ctx,
1299 struct lsa_EnumPrivsAccount *r)
1301 struct dcesrv_handle *h;
1302 struct lsa_account_state *astate;
1304 struct ldb_message **res;
1305 const char * const attrs[] = { "privilege", NULL};
1306 struct ldb_message_element *el;
1309 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1313 r->out.privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
1314 r->out.privs->count = 0;
1315 r->out.privs->unknown = 0;
1316 r->out.privs->set = NULL;
1318 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
1319 if (sidstr == NULL) {
1320 return NT_STATUS_NO_MEMORY;
1323 ret = gendb_search(astate->policy->sam_ldb, mem_ctx, NULL, &res, attrs,
1324 "objectSid=%s", sidstr);
1326 return NT_STATUS_OK;
1329 el = ldb_msg_find_element(res[0], "privilege");
1330 if (el == NULL || el->num_values == 0) {
1331 return NT_STATUS_OK;
1334 r->out.privs->set = talloc_array(r->out.privs,
1335 struct lsa_LUIDAttribute, el->num_values);
1336 if (r->out.privs->set == NULL) {
1337 return NT_STATUS_NO_MEMORY;
1340 for (i=0;i<el->num_values;i++) {
1341 int id = sec_privilege_id((const char *)el->values[i].data);
1343 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1345 r->out.privs->set[i].attribute = 0;
1346 r->out.privs->set[i].luid.low = id;
1347 r->out.privs->set[i].luid.high = 0;
1350 r->out.privs->count = el->num_values;
1352 return NT_STATUS_OK;
1356 lsa_EnumAccountRights
1358 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
1359 TALLOC_CTX *mem_ctx,
1360 struct lsa_EnumAccountRights *r)
1362 struct dcesrv_handle *h;
1363 struct lsa_policy_state *state;
1365 struct ldb_message **res;
1366 const char * const attrs[] = { "privilege", NULL};
1368 struct ldb_message_element *el;
1370 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1374 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
1375 if (sidstr == NULL) {
1376 return NT_STATUS_NO_MEMORY;
1379 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
1380 "(&(objectSid=%s)(privilege=*))", sidstr);
1382 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1385 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1388 DEBUG(3, ("searching for account rights for SID: %s failed: %s",
1389 dom_sid_string(mem_ctx, r->in.sid),
1390 ldb_errstring(state->sam_ldb)));
1391 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1394 el = ldb_msg_find_element(res[0], "privilege");
1395 if (el == NULL || el->num_values == 0) {
1396 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1399 r->out.rights->count = el->num_values;
1400 r->out.rights->names = talloc_array(r->out.rights,
1401 struct lsa_StringLarge, r->out.rights->count);
1402 if (r->out.rights->names == NULL) {
1403 return NT_STATUS_NO_MEMORY;
1406 for (i=0;i<el->num_values;i++) {
1407 r->out.rights->names[i].string = (const char *)el->values[i].data;
1410 return NT_STATUS_OK;
1416 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
1418 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
1419 TALLOC_CTX *mem_ctx,
1420 struct lsa_policy_state *state,
1422 struct dom_sid *sid,
1423 const struct lsa_RightSet *rights)
1426 struct ldb_message *msg;
1427 struct ldb_message_element *el;
1429 struct lsa_EnumAccountRights r2;
1431 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, sid);
1432 if (sidstr == NULL) {
1433 return NT_STATUS_NO_MEMORY;
1436 msg = ldb_msg_new(mem_ctx);
1438 return NT_STATUS_NO_MEMORY;
1441 msg->dn = samdb_search_dn(state->sam_ldb, mem_ctx,
1442 NULL, "objectSid=%s", sidstr);
1443 if (msg->dn == NULL) {
1445 if (ldb_flag == LDB_FLAG_MOD_DELETE) {
1446 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1448 status = samdb_create_foreign_security_principal(state->sam_ldb, mem_ctx,
1450 if (!NT_STATUS_IS_OK(status)) {
1453 return NT_STATUS_NO_SUCH_USER;
1456 if (ldb_msg_add_empty(msg, "privilege", ldb_flag, NULL)) {
1457 return NT_STATUS_NO_MEMORY;
1460 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1463 r2.in.handle = &state->handle->wire_handle;
1465 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
1467 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1468 if (!NT_STATUS_IS_OK(status)) {
1469 ZERO_STRUCTP(r2.out.rights);
1473 for (i=0;i<rights->count;i++) {
1474 if (sec_privilege_id(rights->names[i].string) == -1) {
1475 return NT_STATUS_NO_SUCH_PRIVILEGE;
1478 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1480 for (j=0;j<r2.out.rights->count;j++) {
1481 if (strcasecmp_m(r2.out.rights->names[j].string,
1482 rights->names[i].string) == 0) {
1486 if (j != r2.out.rights->count) continue;
1489 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
1490 if (ret != LDB_SUCCESS) {
1491 return NT_STATUS_NO_MEMORY;
1495 el = ldb_msg_find_element(msg, "privilege");
1497 return NT_STATUS_OK;
1500 ret = ldb_modify(state->sam_ldb, msg);
1502 if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1503 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1505 DEBUG(3, ("Could not %s attributes from %s: %s",
1506 ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add",
1507 ldb_dn_get_linearized(msg->dn), ldb_errstring(state->sam_ldb)));
1508 return NT_STATUS_UNEXPECTED_IO_ERROR;
1511 return NT_STATUS_OK;
1515 lsa_AddPrivilegesToAccount
1517 static NTSTATUS dcesrv_lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1518 struct lsa_AddPrivilegesToAccount *r)
1520 struct lsa_RightSet rights;
1521 struct dcesrv_handle *h;
1522 struct lsa_account_state *astate;
1525 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1529 rights.count = r->in.privs->count;
1530 rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
1531 if (rights.names == NULL) {
1532 return NT_STATUS_NO_MEMORY;
1534 for (i=0;i<rights.count;i++) {
1535 int id = r->in.privs->set[i].luid.low;
1536 if (r->in.privs->set[i].luid.high) {
1537 return NT_STATUS_NO_SUCH_PRIVILEGE;
1539 rights.names[i].string = sec_privilege_name(id);
1540 if (rights.names[i].string == NULL) {
1541 return NT_STATUS_NO_SUCH_PRIVILEGE;
1545 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1546 LDB_FLAG_MOD_ADD, astate->account_sid,
1552 lsa_RemovePrivilegesFromAccount
1554 static NTSTATUS dcesrv_lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1555 struct lsa_RemovePrivilegesFromAccount *r)
1557 struct lsa_RightSet *rights;
1558 struct dcesrv_handle *h;
1559 struct lsa_account_state *astate;
1562 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1566 rights = talloc(mem_ctx, struct lsa_RightSet);
1568 if (r->in.remove_all == 1 &&
1569 r->in.privs == NULL) {
1570 struct lsa_EnumAccountRights r2;
1573 r2.in.handle = &astate->policy->handle->wire_handle;
1574 r2.in.sid = astate->account_sid;
1575 r2.out.rights = rights;
1577 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1578 if (!NT_STATUS_IS_OK(status)) {
1582 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1583 LDB_FLAG_MOD_DELETE, astate->account_sid,
1587 if (r->in.remove_all != 0) {
1588 return NT_STATUS_INVALID_PARAMETER;
1591 rights->count = r->in.privs->count;
1592 rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
1593 if (rights->names == NULL) {
1594 return NT_STATUS_NO_MEMORY;
1596 for (i=0;i<rights->count;i++) {
1597 int id = r->in.privs->set[i].luid.low;
1598 if (r->in.privs->set[i].luid.high) {
1599 return NT_STATUS_NO_SUCH_PRIVILEGE;
1601 rights->names[i].string = sec_privilege_name(id);
1602 if (rights->names[i].string == NULL) {
1603 return NT_STATUS_NO_SUCH_PRIVILEGE;
1607 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1608 LDB_FLAG_MOD_DELETE, astate->account_sid,
1614 lsa_GetQuotasForAccount
1616 static NTSTATUS dcesrv_lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1617 struct lsa_GetQuotasForAccount *r)
1619 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1624 lsa_SetQuotasForAccount
1626 static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1627 struct lsa_SetQuotasForAccount *r)
1629 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1634 lsa_GetSystemAccessAccount
1636 static NTSTATUS dcesrv_lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1637 struct lsa_GetSystemAccessAccount *r)
1639 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1644 lsa_SetSystemAccessAccount
1646 static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1647 struct lsa_SetSystemAccessAccount *r)
1649 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1656 static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1657 struct lsa_CreateSecret *r)
1659 struct dcesrv_handle *policy_handle;
1660 struct lsa_policy_state *policy_state;
1661 struct lsa_secret_state *secret_state;
1662 struct dcesrv_handle *handle;
1663 struct ldb_message **msgs, *msg;
1665 const char *attrs[] = {
1673 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1674 ZERO_STRUCTP(r->out.sec_handle);
1676 policy_state = policy_handle->data;
1678 if (!r->in.name.string) {
1679 return NT_STATUS_INVALID_PARAMETER;
1682 secret_state = talloc(mem_ctx, struct lsa_secret_state);
1683 if (!secret_state) {
1684 return NT_STATUS_NO_MEMORY;
1686 secret_state->policy = policy_state;
1688 msg = ldb_msg_new(mem_ctx);
1690 return NT_STATUS_NO_MEMORY;
1693 if (strncmp("G$", r->in.name.string, 2) == 0) {
1695 name = &r->in.name.string[2];
1696 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
1697 secret_state->global = true;
1699 if (strlen(name) < 1) {
1700 return NT_STATUS_INVALID_PARAMETER;
1703 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
1704 /* search for the secret record */
1705 ret = gendb_search(secret_state->sam_ldb,
1706 mem_ctx, policy_state->system_dn, &msgs, attrs,
1707 "(&(cn=%s)(objectclass=secret))",
1710 return NT_STATUS_OBJECT_NAME_COLLISION;
1714 DEBUG(0,("Failure searching for CN=%s: %s\n",
1715 name2, ldb_errstring(secret_state->sam_ldb)));
1716 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1719 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
1720 if (!name2 || ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
1721 return NT_STATUS_NO_MEMORY;
1724 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
1727 secret_state->global = false;
1729 name = r->in.name.string;
1730 if (strlen(name) < 1) {
1731 return NT_STATUS_INVALID_PARAMETER;
1734 secret_state->sam_ldb = talloc_reference(secret_state,
1735 secrets_db_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
1736 /* search for the secret record */
1737 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
1738 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
1740 "(&(cn=%s)(objectclass=secret))",
1741 ldb_binary_encode_string(mem_ctx, name));
1743 return NT_STATUS_OBJECT_NAME_COLLISION;
1747 DEBUG(0,("Failure searching for CN=%s: %s\n",
1748 name, ldb_errstring(secret_state->sam_ldb)));
1749 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1752 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name);
1753 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
1756 /* pull in all the template attributes. Note this is always from the global samdb */
1757 ret = samdb_copy_template(secret_state->policy->sam_ldb, msg,
1760 DEBUG(0,("Failed to load TemplateSecret from samdb: %s\n",
1762 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1765 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
1767 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
1769 /* create the secret */
1770 ret = ldb_add(secret_state->sam_ldb, msg);
1772 DEBUG(0,("Failed to create secret record %s: %s\n",
1773 ldb_dn_get_linearized(msg->dn),
1774 ldb_errstring(secret_state->sam_ldb)));
1775 return NT_STATUS_ACCESS_DENIED;
1778 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
1780 return NT_STATUS_NO_MEMORY;
1783 handle->data = talloc_steal(handle, secret_state);
1785 secret_state->access_mask = r->in.access_mask;
1786 secret_state->policy = talloc_reference(secret_state, policy_state);
1788 *r->out.sec_handle = handle->wire_handle;
1790 return NT_STATUS_OK;
1797 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1798 struct lsa_OpenSecret *r)
1800 struct dcesrv_handle *policy_handle;
1802 struct lsa_policy_state *policy_state;
1803 struct lsa_secret_state *secret_state;
1804 struct dcesrv_handle *handle;
1805 struct ldb_message **msgs;
1806 const char *attrs[] = {
1814 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1815 ZERO_STRUCTP(r->out.sec_handle);
1816 policy_state = policy_handle->data;
1818 if (!r->in.name.string) {
1819 return NT_STATUS_INVALID_PARAMETER;
1822 secret_state = talloc(mem_ctx, struct lsa_secret_state);
1823 if (!secret_state) {
1824 return NT_STATUS_NO_MEMORY;
1826 secret_state->policy = policy_state;
1828 if (strncmp("G$", r->in.name.string, 2) == 0) {
1829 name = &r->in.name.string[2];
1830 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
1831 secret_state->global = true;
1833 if (strlen(name) < 1) {
1834 return NT_STATUS_INVALID_PARAMETER;
1837 /* search for the secret record */
1838 ret = gendb_search(secret_state->sam_ldb,
1839 mem_ctx, policy_state->system_dn, &msgs, attrs,
1840 "(&(cn=%s Secret)(objectclass=secret))",
1841 ldb_binary_encode_string(mem_ctx, name));
1843 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1847 DEBUG(0,("Found %d records matching DN %s\n", ret,
1848 ldb_dn_get_linearized(policy_state->system_dn)));
1849 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1853 secret_state->sam_ldb = talloc_reference(secret_state,
1854 secrets_db_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
1856 secret_state->global = false;
1857 name = r->in.name.string;
1858 if (strlen(name) < 1) {
1859 return NT_STATUS_INVALID_PARAMETER;
1862 /* search for the secret record */
1863 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
1864 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
1866 "(&(cn=%s)(objectclass=secret))",
1867 ldb_binary_encode_string(mem_ctx, name));
1869 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1873 DEBUG(0,("Found %d records matching CN=%s\n",
1874 ret, ldb_binary_encode_string(mem_ctx, name)));
1875 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1879 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
1881 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
1883 return NT_STATUS_NO_MEMORY;
1886 handle->data = talloc_steal(handle, secret_state);
1888 secret_state->access_mask = r->in.access_mask;
1889 secret_state->policy = talloc_reference(secret_state, policy_state);
1891 *r->out.sec_handle = handle->wire_handle;
1893 return NT_STATUS_OK;
1900 static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1901 struct lsa_SetSecret *r)
1904 struct dcesrv_handle *h;
1905 struct lsa_secret_state *secret_state;
1906 struct ldb_message *msg;
1907 DATA_BLOB session_key;
1908 DATA_BLOB crypt_secret, secret;
1911 NTSTATUS status = NT_STATUS_OK;
1913 struct timeval now = timeval_current();
1914 NTTIME nt_now = timeval_to_nttime(&now);
1916 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
1918 secret_state = h->data;
1920 msg = ldb_msg_new(mem_ctx);
1922 return NT_STATUS_NO_MEMORY;
1925 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
1927 return NT_STATUS_NO_MEMORY;
1929 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
1930 if (!NT_STATUS_IS_OK(status)) {
1934 if (r->in.old_val) {
1936 crypt_secret.data = r->in.old_val->data;
1937 crypt_secret.length = r->in.old_val->size;
1939 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
1940 if (!NT_STATUS_IS_OK(status)) {
1944 val.data = secret.data;
1945 val.length = secret.length;
1948 if (samdb_msg_add_value(secret_state->sam_ldb,
1949 mem_ctx, msg, "priorValue", &val) != 0) {
1950 return NT_STATUS_NO_MEMORY;
1953 /* set old value mtime */
1954 if (samdb_msg_add_uint64(secret_state->sam_ldb,
1955 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
1956 return NT_STATUS_NO_MEMORY;
1959 if (!r->in.new_val) {
1960 /* This behaviour varies depending of if this is a local, or a global secret... */
1961 if (secret_state->global) {
1962 /* set old value mtime */
1963 if (samdb_msg_add_uint64(secret_state->sam_ldb,
1964 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
1965 return NT_STATUS_NO_MEMORY;
1968 if (samdb_msg_add_delete(secret_state->sam_ldb,
1969 mem_ctx, msg, "currentValue")) {
1970 return NT_STATUS_NO_MEMORY;
1972 if (samdb_msg_add_delete(secret_state->sam_ldb,
1973 mem_ctx, msg, "lastSetTime")) {
1974 return NT_STATUS_NO_MEMORY;
1980 if (r->in.new_val) {
1982 crypt_secret.data = r->in.new_val->data;
1983 crypt_secret.length = r->in.new_val->size;
1985 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
1986 if (!NT_STATUS_IS_OK(status)) {
1990 val.data = secret.data;
1991 val.length = secret.length;
1994 if (samdb_msg_add_value(secret_state->sam_ldb,
1995 mem_ctx, msg, "currentValue", &val) != 0) {
1996 return NT_STATUS_NO_MEMORY;
1999 /* set new value mtime */
2000 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2001 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2002 return NT_STATUS_NO_MEMORY;
2005 /* If the old value is not set, then migrate the
2006 * current value to the old value */
2007 if (!r->in.old_val) {
2008 const struct ldb_val *new_val;
2009 NTTIME last_set_time;
2010 struct ldb_message **res;
2011 const char *attrs[] = {
2017 /* search for the secret record */
2018 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
2019 secret_state->secret_dn, &res, attrs);
2021 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2025 DEBUG(0,("Found %d records matching dn=%s\n", ret,
2026 ldb_dn_get_linearized(secret_state->secret_dn)));
2027 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2030 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2031 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2035 if (samdb_msg_add_value(secret_state->sam_ldb,
2036 mem_ctx, msg, "priorValue",
2038 return NT_STATUS_NO_MEMORY;
2042 /* set new value mtime */
2043 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2044 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2045 mem_ctx, msg, "priorSetTime", last_set_time) != 0) {
2046 return NT_STATUS_NO_MEMORY;
2052 /* modify the samdb record */
2053 ret = samdb_replace(secret_state->sam_ldb, mem_ctx, msg);
2055 /* we really need samdb.c to return NTSTATUS */
2056 return NT_STATUS_UNSUCCESSFUL;
2059 return NT_STATUS_OK;
2066 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2067 struct lsa_QuerySecret *r)
2069 struct dcesrv_handle *h;
2070 struct lsa_secret_state *secret_state;
2071 struct ldb_message *msg;
2072 DATA_BLOB session_key;
2073 DATA_BLOB crypt_secret, secret;
2075 struct ldb_message **res;
2076 const char *attrs[] = {
2086 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2088 secret_state = h->data;
2090 /* pull all the user attributes */
2091 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2092 secret_state->secret_dn, &res, attrs);
2094 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2098 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2099 if (!NT_STATUS_IS_OK(nt_status)) {
2103 if (r->in.old_val) {
2104 const struct ldb_val *prior_val;
2105 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2106 if (!r->out.old_val) {
2107 return NT_STATUS_NO_MEMORY;
2109 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
2111 if (prior_val && prior_val->length) {
2112 secret.data = prior_val->data;
2113 secret.length = prior_val->length;
2116 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2117 if (!crypt_secret.length) {
2118 return NT_STATUS_NO_MEMORY;
2120 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2121 if (!r->out.old_val->buf) {
2122 return NT_STATUS_NO_MEMORY;
2124 r->out.old_val->buf->size = crypt_secret.length;
2125 r->out.old_val->buf->length = crypt_secret.length;
2126 r->out.old_val->buf->data = crypt_secret.data;
2130 if (r->in.old_mtime) {
2131 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2132 if (!r->out.old_mtime) {
2133 return NT_STATUS_NO_MEMORY;
2135 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
2138 if (r->in.new_val) {
2139 const struct ldb_val *new_val;
2140 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2141 if (!r->out.new_val) {
2142 return NT_STATUS_NO_MEMORY;
2145 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2147 if (new_val && new_val->length) {
2148 secret.data = new_val->data;
2149 secret.length = new_val->length;
2152 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2153 if (!crypt_secret.length) {
2154 return NT_STATUS_NO_MEMORY;
2156 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2157 if (!r->out.new_val->buf) {
2158 return NT_STATUS_NO_MEMORY;
2160 r->out.new_val->buf->length = crypt_secret.length;
2161 r->out.new_val->buf->size = crypt_secret.length;
2162 r->out.new_val->buf->data = crypt_secret.data;
2166 if (r->in.new_mtime) {
2167 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2168 if (!r->out.new_mtime) {
2169 return NT_STATUS_NO_MEMORY;
2171 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2174 return NT_STATUS_OK;
2181 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
2182 TALLOC_CTX *mem_ctx,
2183 struct lsa_LookupPrivValue *r)
2185 struct dcesrv_handle *h;
2186 struct lsa_policy_state *state;
2189 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2193 id = sec_privilege_id(r->in.name->string);
2195 return NT_STATUS_NO_SUCH_PRIVILEGE;
2198 r->out.luid->low = id;
2199 r->out.luid->high = 0;
2201 return NT_STATUS_OK;
2208 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
2209 TALLOC_CTX *mem_ctx,
2210 struct lsa_LookupPrivName *r)
2212 struct dcesrv_handle *h;
2213 struct lsa_policy_state *state;
2214 const char *privname;
2216 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2220 if (r->in.luid->high != 0) {
2221 return NT_STATUS_NO_SUCH_PRIVILEGE;
2224 privname = sec_privilege_name(r->in.luid->low);
2225 if (privname == NULL) {
2226 return NT_STATUS_NO_SUCH_PRIVILEGE;
2229 r->out.name = talloc(mem_ctx, struct lsa_StringLarge);
2230 if (r->out.name == NULL) {
2231 return NT_STATUS_NO_MEMORY;
2233 r->out.name->string = privname;
2235 return NT_STATUS_OK;
2240 lsa_LookupPrivDisplayName
2242 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
2243 TALLOC_CTX *mem_ctx,
2244 struct lsa_LookupPrivDisplayName *r)
2246 struct dcesrv_handle *h;
2247 struct lsa_policy_state *state;
2250 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2254 id = sec_privilege_id(r->in.name->string);
2256 return NT_STATUS_NO_SUCH_PRIVILEGE;
2259 r->out.disp_name = talloc(mem_ctx, struct lsa_StringLarge);
2260 if (r->out.disp_name == NULL) {
2261 return NT_STATUS_NO_MEMORY;
2264 r->out.disp_name->string = sec_privilege_display_name(id, r->in.language_id);
2265 if (r->out.disp_name->string == NULL) {
2266 return NT_STATUS_INTERNAL_ERROR;
2269 return NT_STATUS_OK;
2276 static NTSTATUS dcesrv_lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2277 struct lsa_DeleteObject *r)
2279 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2284 lsa_EnumAccountsWithUserRight
2286 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
2287 TALLOC_CTX *mem_ctx,
2288 struct lsa_EnumAccountsWithUserRight *r)
2290 struct dcesrv_handle *h;
2291 struct lsa_policy_state *state;
2293 struct ldb_message **res;
2294 const char * const attrs[] = { "objectSid", NULL};
2295 const char *privname;
2297 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2301 if (r->in.name == NULL) {
2302 return NT_STATUS_NO_SUCH_PRIVILEGE;
2305 privname = r->in.name->string;
2306 if (sec_privilege_id(privname) == -1) {
2307 return NT_STATUS_NO_SUCH_PRIVILEGE;
2310 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
2311 "privilege=%s", privname);
2313 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2316 return NT_STATUS_NO_MORE_ENTRIES;
2319 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2320 if (r->out.sids->sids == NULL) {
2321 return NT_STATUS_NO_MEMORY;
2323 for (i=0;i<ret;i++) {
2324 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2325 res[i], "objectSid");
2326 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2328 r->out.sids->num_sids = ret;
2330 return NT_STATUS_OK;
2335 lsa_AddAccountRights
2337 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
2338 TALLOC_CTX *mem_ctx,
2339 struct lsa_AddAccountRights *r)
2341 struct dcesrv_handle *h;
2342 struct lsa_policy_state *state;
2344 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2348 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2350 r->in.sid, r->in.rights);
2355 lsa_RemoveAccountRights
2357 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
2358 TALLOC_CTX *mem_ctx,
2359 struct lsa_RemoveAccountRights *r)
2361 struct dcesrv_handle *h;
2362 struct lsa_policy_state *state;
2364 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2368 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2369 LDB_FLAG_MOD_DELETE,
2370 r->in.sid, r->in.rights);
2375 lsa_StorePrivateData
2377 static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2378 struct lsa_StorePrivateData *r)
2380 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2385 lsa_RetrievePrivateData
2387 static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2388 struct lsa_RetrievePrivateData *r)
2390 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2397 static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2398 struct lsa_GetUserName *r)
2400 NTSTATUS status = NT_STATUS_OK;
2401 const char *account_name;
2402 const char *authority_name;
2403 struct lsa_String *_account_name;
2404 struct lsa_StringPointer *_authority_name = NULL;
2406 /* this is what w2k3 does */
2407 r->out.account_name = r->in.account_name;
2408 r->out.authority_name = r->in.authority_name;
2410 if (r->in.account_name && r->in.account_name->string) {
2411 return NT_STATUS_INVALID_PARAMETER;
2414 if (r->in.authority_name &&
2415 r->in.authority_name->string &&
2416 r->in.authority_name->string->string) {
2417 return NT_STATUS_INVALID_PARAMETER;
2420 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
2421 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
2423 _account_name = talloc(mem_ctx, struct lsa_String);
2424 NT_STATUS_HAVE_NO_MEMORY(_account_name);
2425 _account_name->string = account_name;
2427 if (r->in.authority_name) {
2428 _authority_name = talloc(mem_ctx, struct lsa_StringPointer);
2429 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
2430 _authority_name->string = talloc(mem_ctx, struct lsa_String);
2431 NT_STATUS_HAVE_NO_MEMORY(_authority_name->string);
2432 _authority_name->string->string = authority_name;
2435 r->out.account_name = _account_name;
2436 r->out.authority_name = _authority_name;
2444 static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
2445 TALLOC_CTX *mem_ctx,
2446 struct lsa_SetInfoPolicy2 *r)
2448 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2452 lsa_QueryDomainInformationPolicy
2454 static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2455 TALLOC_CTX *mem_ctx,
2456 struct lsa_QueryDomainInformationPolicy *r)
2458 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2462 lsa_SetDomInfoPolicy
2464 static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2465 TALLOC_CTX *mem_ctx,
2466 struct lsa_SetDomainInformationPolicy *r)
2468 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2474 static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
2475 TALLOC_CTX *mem_ctx,
2476 struct lsa_TestCall *r)
2478 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2484 static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2485 struct lsa_CREDRWRITE *r)
2487 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2494 static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2495 struct lsa_CREDRREAD *r)
2497 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2504 static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2505 struct lsa_CREDRENUMERATE *r)
2507 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2512 lsa_CREDRWRITEDOMAINCREDENTIALS
2514 static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2515 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
2517 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2522 lsa_CREDRREADDOMAINCREDENTIALS
2524 static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2525 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
2527 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2534 static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2535 struct lsa_CREDRDELETE *r)
2537 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2542 lsa_CREDRGETTARGETINFO
2544 static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2545 struct lsa_CREDRGETTARGETINFO *r)
2547 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2552 lsa_CREDRPROFILELOADED
2554 static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2555 struct lsa_CREDRPROFILELOADED *r)
2557 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2562 lsa_CREDRGETSESSIONTYPES
2564 static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2565 struct lsa_CREDRGETSESSIONTYPES *r)
2567 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2572 lsa_LSARREGISTERAUDITEVENT
2574 static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2575 struct lsa_LSARREGISTERAUDITEVENT *r)
2577 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2582 lsa_LSARGENAUDITEVENT
2584 static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2585 struct lsa_LSARGENAUDITEVENT *r)
2587 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2592 lsa_LSARUNREGISTERAUDITEVENT
2594 static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2595 struct lsa_LSARUNREGISTERAUDITEVENT *r)
2597 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2602 lsa_lsaRQueryForestTrustInformation
2604 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2605 struct lsa_lsaRQueryForestTrustInformation *r)
2607 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2612 lsa_LSARSETFORESTTRUSTINFORMATION
2614 static NTSTATUS dcesrv_lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2615 struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
2617 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2624 static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2625 struct lsa_CREDRRENAME *r)
2627 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2633 lsa_LSAROPENPOLICYSCE
2635 static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2636 struct lsa_LSAROPENPOLICYSCE *r)
2638 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2643 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
2645 static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2646 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
2648 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2653 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
2655 static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2656 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
2658 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2663 lsa_LSARADTREPORTSECURITYEVENT
2665 static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2666 struct lsa_LSARADTREPORTSECURITYEVENT *r)
2668 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2672 /* include the generated boilerplate */
2673 #include "librpc/gen_ndr/ndr_lsa_s.c"
2677 /*****************************************
2678 NOTE! The remaining calls below were
2679 removed in w2k3, so the DCESRV_FAULT()
2680 replies are the correct implementation. Do
2681 not try and fill these in with anything else
2682 ******************************************/
2685 dssetup_DsRoleDnsNameToFlatName
2687 static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2688 struct dssetup_DsRoleDnsNameToFlatName *r)
2690 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2695 dssetup_DsRoleDcAsDc
2697 static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2698 struct dssetup_DsRoleDcAsDc *r)
2700 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2705 dssetup_DsRoleDcAsReplica
2707 static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2708 struct dssetup_DsRoleDcAsReplica *r)
2710 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2715 dssetup_DsRoleDemoteDc
2717 static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2718 struct dssetup_DsRoleDemoteDc *r)
2720 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2725 dssetup_DsRoleGetDcOperationProgress
2727 static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2728 struct dssetup_DsRoleGetDcOperationProgress *r)
2730 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2735 dssetup_DsRoleGetDcOperationResults
2737 static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2738 struct dssetup_DsRoleGetDcOperationResults *r)
2740 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2745 dssetup_DsRoleCancel
2747 static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2748 struct dssetup_DsRoleCancel *r)
2750 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2755 dssetup_DsRoleServerSaveStateForUpgrade
2757 static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2758 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
2760 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2765 dssetup_DsRoleUpgradeDownlevelServer
2767 static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2768 struct dssetup_DsRoleUpgradeDownlevelServer *r)
2770 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2775 dssetup_DsRoleAbortDownlevelServerUpgrade
2777 static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2778 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
2780 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2784 /* include the generated boilerplate */
2785 #include "librpc/gen_ndr/ndr_dssetup_s.c"
2787 NTSTATUS dcerpc_server_lsa_init(void)
2791 ret = dcerpc_server_dssetup_init();
2792 if (!NT_STATUS_IS_OK(ret)) {
2795 ret = dcerpc_server_lsarpc_init();
2796 if (!NT_STATUS_IS_OK(ret)) {