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"
26 #include "system/kerberos.h"
27 #include "auth/kerberos/kerberos.h"
30 this type allows us to distinguish handle types
34 state associated with a lsa_OpenAccount() operation
36 struct lsa_account_state {
37 struct lsa_policy_state *policy;
39 struct dom_sid *account_sid;
44 state associated with a lsa_OpenSecret() operation
46 struct lsa_secret_state {
47 struct lsa_policy_state *policy;
49 struct ldb_dn *secret_dn;
50 struct ldb_context *sam_ldb;
55 state associated with a lsa_OpenTrustedDomain() operation
57 struct lsa_trusted_domain_state {
58 struct lsa_policy_state *policy;
60 struct ldb_dn *trusted_domain_dn;
63 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
65 struct lsa_EnumAccountRights *r);
67 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
69 struct lsa_policy_state *state,
72 const struct lsa_RightSet *rights);
77 static NTSTATUS dcesrv_lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
80 struct dcesrv_handle *h;
82 *r->out.handle = *r->in.handle;
84 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
88 ZERO_STRUCTP(r->out.handle);
97 static NTSTATUS dcesrv_lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
100 return NT_STATUS_NOT_SUPPORTED;
107 static NTSTATUS dcesrv_lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
108 struct lsa_DeleteObject *r)
110 struct dcesrv_handle *h;
113 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
115 if (h->wire_handle.handle_type == LSA_HANDLE_SECRET) {
116 struct lsa_secret_state *secret_state = h->data;
118 /* Ensure user is permitted to delete this... */
119 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
121 case SECURITY_SYSTEM:
122 case SECURITY_ADMINISTRATOR:
125 /* Users and annonymous are not allowed delete things */
126 return NT_STATUS_ACCESS_DENIED;
129 ret = ldb_delete(secret_state->sam_ldb,
130 secret_state->secret_dn);
133 return NT_STATUS_INVALID_HANDLE;
136 ZERO_STRUCTP(r->out.handle);
139 } else if (h->wire_handle.handle_type == LSA_HANDLE_TRUSTED_DOMAIN) {
140 struct lsa_trusted_domain_state *trusted_domain_state = h->data;
141 ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
142 trusted_domain_state->trusted_domain_dn);
145 return NT_STATUS_INVALID_HANDLE;
148 ZERO_STRUCTP(r->out.handle);
151 } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
152 struct lsa_RightSet *rights;
153 struct lsa_account_state *astate;
154 struct lsa_EnumAccountRights r2;
157 rights = talloc(mem_ctx, struct lsa_RightSet);
159 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
163 r2.in.handle = &astate->policy->handle->wire_handle;
164 r2.in.sid = astate->account_sid;
165 r2.out.rights = rights;
167 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
168 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
172 if (!NT_STATUS_IS_OK(status)) {
176 status = dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
177 LDB_FLAG_MOD_DELETE, astate->account_sid,
179 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
183 if (!NT_STATUS_IS_OK(status)) {
187 ZERO_STRUCTP(r->out.handle);
190 return NT_STATUS_INVALID_HANDLE;
197 static NTSTATUS dcesrv_lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
198 struct lsa_EnumPrivs *r)
200 struct dcesrv_handle *h;
201 struct lsa_policy_state *state;
203 const char *privname;
205 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
209 i = *r->in.resume_handle;
212 while ((privname = sec_privilege_name(i)) &&
213 r->out.privs->count < r->in.max_count) {
214 struct lsa_PrivEntry *e;
216 r->out.privs->privs = talloc_realloc(r->out.privs,
218 struct lsa_PrivEntry,
219 r->out.privs->count+1);
220 if (r->out.privs->privs == NULL) {
221 return NT_STATUS_NO_MEMORY;
223 e = &r->out.privs->privs[r->out.privs->count];
226 e->name.string = privname;
227 r->out.privs->count++;
231 *r->out.resume_handle = i;
240 static NTSTATUS dcesrv_lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
241 struct lsa_QuerySecurity *r)
243 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
250 static NTSTATUS dcesrv_lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
251 struct lsa_SetSecObj *r)
253 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
260 static NTSTATUS dcesrv_lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
261 struct lsa_ChangePassword *r)
263 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
267 dssetup_DsRoleGetPrimaryDomainInformation
269 This is not an LSA call, but is the only call left on the DSSETUP
270 pipe (after the pipe was truncated), and needs lsa_get_policy_state
272 static WERROR dcesrv_dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state *dce_call,
274 struct dssetup_DsRoleGetPrimaryDomainInformation *r)
276 union dssetup_DsRoleInfo *info;
278 info = talloc(mem_ctx, union dssetup_DsRoleInfo);
279 W_ERROR_HAVE_NO_MEMORY(info);
281 switch (r->in.level) {
282 case DS_ROLE_BASIC_INFORMATION:
284 enum dssetup_DsRole role = DS_ROLE_STANDALONE_SERVER;
286 const char *domain = NULL;
287 const char *dns_domain = NULL;
288 const char *forest = NULL;
289 struct GUID domain_guid;
290 struct lsa_policy_state *state;
292 NTSTATUS status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
293 if (!NT_STATUS_IS_OK(status)) {
294 return ntstatus_to_werror(status);
297 ZERO_STRUCT(domain_guid);
299 switch (lp_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
300 case ROLE_STANDALONE:
301 role = DS_ROLE_STANDALONE_SERVER;
303 case ROLE_DOMAIN_MEMBER:
304 role = DS_ROLE_MEMBER_SERVER;
306 case ROLE_DOMAIN_CONTROLLER:
307 if (samdb_is_pdc(state->sam_ldb)) {
308 role = DS_ROLE_PRIMARY_DC;
310 role = DS_ROLE_BACKUP_DC;
315 switch (lp_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
316 case ROLE_STANDALONE:
317 domain = talloc_strdup(mem_ctx, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx));
318 W_ERROR_HAVE_NO_MEMORY(domain);
320 case ROLE_DOMAIN_MEMBER:
321 domain = talloc_strdup(mem_ctx, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx));
322 W_ERROR_HAVE_NO_MEMORY(domain);
323 /* TODO: what is with dns_domain and forest and guid? */
325 case ROLE_DOMAIN_CONTROLLER:
326 flags = DS_ROLE_PRIMARY_DS_RUNNING;
328 if (state->mixed_domain == 1) {
329 flags |= DS_ROLE_PRIMARY_DS_MIXED_MODE;
332 domain = state->domain_name;
333 dns_domain = state->domain_dns;
334 forest = state->forest_dns;
336 domain_guid = state->domain_guid;
337 flags |= DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT;
341 info->basic.role = role;
342 info->basic.flags = flags;
343 info->basic.domain = domain;
344 info->basic.dns_domain = dns_domain;
345 info->basic.forest = forest;
346 info->basic.domain_guid = domain_guid;
351 case DS_ROLE_UPGRADE_STATUS:
353 info->upgrade.upgrading = DS_ROLE_NOT_UPGRADING;
354 info->upgrade.previous_role = DS_ROLE_PREVIOUS_UNKNOWN;
359 case DS_ROLE_OP_STATUS:
361 info->opstatus.status = DS_ROLE_OP_IDLE;
367 return WERR_INVALID_PARAM;
370 return WERR_INVALID_PARAM;
375 fill in the AccountDomain info
377 static NTSTATUS dcesrv_lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
378 struct lsa_DomainInfo *info)
380 info->name.string = state->domain_name;
381 info->sid = state->domain_sid;
387 fill in the DNS domain info
389 static NTSTATUS dcesrv_lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
390 struct lsa_DnsDomainInfo *info)
392 info->name.string = state->domain_name;
393 info->sid = state->domain_sid;
394 info->dns_domain.string = state->domain_dns;
395 info->dns_forest.string = state->forest_dns;
396 info->domain_guid = state->domain_guid;
404 static NTSTATUS dcesrv_lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
405 struct lsa_QueryInfoPolicy2 *r)
407 struct lsa_policy_state *state;
408 struct dcesrv_handle *h;
412 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
416 r->out.info = talloc(mem_ctx, union lsa_PolicyInformation);
418 return NT_STATUS_NO_MEMORY;
421 ZERO_STRUCTP(r->out.info);
423 switch (r->in.level) {
424 case LSA_POLICY_INFO_DOMAIN:
425 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
426 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &r->out.info->account_domain);
428 case LSA_POLICY_INFO_DNS:
429 return dcesrv_lsa_info_DNS(state, mem_ctx, &r->out.info->dns);
430 case LSA_POLICY_INFO_DB:
431 case LSA_POLICY_INFO_AUDIT_FULL_SET:
432 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
433 return NT_STATUS_INVALID_PARAMETER;
436 return NT_STATUS_INVALID_INFO_CLASS;
442 static NTSTATUS dcesrv_lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
443 struct lsa_QueryInfoPolicy *r)
445 struct lsa_QueryInfoPolicy2 r2;
448 r2.in.handle = r->in.handle;
449 r2.in.level = r->in.level;
451 status = dcesrv_lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
453 r->out.info = r2.out.info;
461 static NTSTATUS dcesrv_lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
462 struct lsa_SetInfoPolicy *r)
464 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
471 static NTSTATUS dcesrv_lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
472 struct lsa_ClearAuditLog *r)
474 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
481 This call does not seem to have any long-term effects, hence no database operations
483 static NTSTATUS dcesrv_lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
484 struct lsa_CreateAccount *r)
486 struct lsa_account_state *astate;
488 struct lsa_policy_state *state;
489 struct dcesrv_handle *h, *ah;
491 ZERO_STRUCTP(r->out.acct_handle);
493 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
497 astate = talloc(dce_call->conn, struct lsa_account_state);
498 if (astate == NULL) {
499 return NT_STATUS_NO_MEMORY;
502 astate->account_sid = dom_sid_dup(astate, r->in.sid);
503 if (astate->account_sid == NULL) {
505 return NT_STATUS_NO_MEMORY;
508 astate->policy = talloc_reference(astate, state);
509 astate->access_mask = r->in.access_mask;
511 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
514 return NT_STATUS_NO_MEMORY;
517 ah->data = talloc_steal(ah, astate);
519 *r->out.acct_handle = ah->wire_handle;
528 static NTSTATUS dcesrv_lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
529 struct lsa_EnumAccounts *r)
531 struct dcesrv_handle *h;
532 struct lsa_policy_state *state;
534 struct ldb_message **res;
535 const char * const attrs[] = { "objectSid", NULL};
538 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
542 /* NOTE: This call must only return accounts that have at least
545 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
546 "(&(objectSid=*)(privilege=*))");
548 return NT_STATUS_NO_SUCH_USER;
551 if (*r->in.resume_handle >= ret) {
552 return NT_STATUS_NO_MORE_ENTRIES;
555 count = ret - *r->in.resume_handle;
556 if (count > r->in.num_entries) {
557 count = r->in.num_entries;
561 return NT_STATUS_NO_MORE_ENTRIES;
564 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, count);
565 if (r->out.sids->sids == NULL) {
566 return NT_STATUS_NO_MEMORY;
569 for (i=0;i<count;i++) {
570 r->out.sids->sids[i].sid =
571 samdb_result_dom_sid(r->out.sids->sids,
572 res[i + *r->in.resume_handle],
574 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
577 r->out.sids->num_sids = count;
578 *r->out.resume_handle = count + *r->in.resume_handle;
586 lsa_CreateTrustedDomainEx2
588 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
590 struct lsa_CreateTrustedDomainEx2 *r)
592 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
596 lsa_CreateTrustedDomainEx
598 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
600 struct lsa_CreateTrustedDomainEx *r)
602 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
606 lsa_CreateTrustedDomain
608 static NTSTATUS dcesrv_lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
609 struct lsa_CreateTrustedDomain *r)
611 struct dcesrv_handle *policy_handle;
612 struct lsa_policy_state *policy_state;
613 struct lsa_trusted_domain_state *trusted_domain_state;
614 struct dcesrv_handle *handle;
615 struct ldb_message **msgs, *msg;
616 const char *attrs[] = {
622 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
623 ZERO_STRUCTP(r->out.trustdom_handle);
625 policy_state = policy_handle->data;
627 if (!r->in.info->name.string) {
628 return NT_STATUS_INVALID_PARAMETER;
630 name = r->in.info->name.string;
632 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
633 if (!trusted_domain_state) {
634 return NT_STATUS_NO_MEMORY;
636 trusted_domain_state->policy = policy_state;
638 msg = ldb_msg_new(mem_ctx);
640 return NT_STATUS_NO_MEMORY;
643 /* search for the trusted_domain record */
644 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
645 mem_ctx, policy_state->system_dn, &msgs, attrs,
646 "(&(cn=%s)(objectclass=trustedDomain))",
647 ldb_binary_encode_string(mem_ctx, r->in.info->name.string));
649 return NT_STATUS_OBJECT_NAME_COLLISION;
652 if (ret < 0 || ret > 1) {
653 DEBUG(0,("Found %d records matching DN %s\n", ret,
654 ldb_dn_get_linearized(policy_state->system_dn)));
655 return NT_STATUS_INTERNAL_DB_CORRUPTION;
658 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
659 if ( ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name)) {
660 return NT_STATUS_NO_MEMORY;
663 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "flatname", name);
665 if (r->in.info->sid) {
666 const char *sid_string = dom_sid_string(mem_ctx, r->in.info->sid);
668 return NT_STATUS_NO_MEMORY;
671 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "securityIdentifier", sid_string);
674 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "objectClass", "trustedDomain");
676 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
678 /* create the trusted_domain */
679 ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg);
683 case LDB_ERR_ENTRY_ALREADY_EXISTS:
684 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
685 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
686 ldb_dn_get_linearized(msg->dn),
687 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
688 return NT_STATUS_DOMAIN_EXISTS;
689 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
690 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
691 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
692 ldb_dn_get_linearized(msg->dn),
693 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
694 return NT_STATUS_ACCESS_DENIED;
696 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
697 DEBUG(0,("Failed to create user record %s: %s\n",
698 ldb_dn_get_linearized(msg->dn),
699 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
700 return NT_STATUS_INTERNAL_DB_CORRUPTION;
703 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
705 return NT_STATUS_NO_MEMORY;
708 handle->data = talloc_steal(handle, trusted_domain_state);
710 trusted_domain_state->access_mask = r->in.access_mask;
711 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
713 *r->out.trustdom_handle = handle->wire_handle;
719 lsa_OpenTrustedDomain
721 static NTSTATUS dcesrv_lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
722 struct lsa_OpenTrustedDomain *r)
724 struct dcesrv_handle *policy_handle;
726 struct lsa_policy_state *policy_state;
727 struct lsa_trusted_domain_state *trusted_domain_state;
728 struct dcesrv_handle *handle;
729 struct ldb_message **msgs;
730 const char *attrs[] = {
734 const char *sid_string;
737 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
738 ZERO_STRUCTP(r->out.trustdom_handle);
739 policy_state = policy_handle->data;
741 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
742 if (!trusted_domain_state) {
743 return NT_STATUS_NO_MEMORY;
745 trusted_domain_state->policy = policy_state;
747 sid_string = dom_sid_string(mem_ctx, r->in.sid);
749 return NT_STATUS_NO_MEMORY;
752 /* search for the trusted_domain record */
753 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
754 mem_ctx, policy_state->system_dn, &msgs, attrs,
755 "(&(securityIdentifier=%s)(objectclass=trustedDomain))",
758 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
762 DEBUG(0,("Found %d records matching DN %s\n", ret,
763 ldb_dn_get_linearized(policy_state->system_dn)));
764 return NT_STATUS_INTERNAL_DB_CORRUPTION;
767 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
769 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
771 return NT_STATUS_NO_MEMORY;
774 handle->data = talloc_steal(handle, trusted_domain_state);
776 trusted_domain_state->access_mask = r->in.access_mask;
777 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
779 *r->out.trustdom_handle = handle->wire_handle;
786 lsa_OpenTrustedDomainByName
788 static NTSTATUS dcesrv_lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
790 struct lsa_OpenTrustedDomainByName *r)
792 struct dcesrv_handle *policy_handle;
794 struct lsa_policy_state *policy_state;
795 struct lsa_trusted_domain_state *trusted_domain_state;
796 struct dcesrv_handle *handle;
797 struct ldb_message **msgs;
798 const char *attrs[] = {
804 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
805 ZERO_STRUCTP(r->out.trustdom_handle);
806 policy_state = policy_handle->data;
808 if (!r->in.name.string) {
809 return NT_STATUS_INVALID_PARAMETER;
812 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
813 if (!trusted_domain_state) {
814 return NT_STATUS_NO_MEMORY;
816 trusted_domain_state->policy = policy_state;
818 /* search for the trusted_domain record */
819 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
820 mem_ctx, policy_state->system_dn, &msgs, attrs,
821 "(&(flatname=%s)(objectclass=trustedDomain))",
822 ldb_binary_encode_string(mem_ctx, r->in.name.string));
824 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
828 DEBUG(0,("Found %d records matching DN %s\n", ret,
829 ldb_dn_get_linearized(policy_state->system_dn)));
830 return NT_STATUS_INTERNAL_DB_CORRUPTION;
833 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
835 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
837 return NT_STATUS_NO_MEMORY;
840 handle->data = talloc_steal(handle, trusted_domain_state);
842 trusted_domain_state->access_mask = r->in.access_mask;
843 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
845 *r->out.trustdom_handle = handle->wire_handle;
853 lsa_SetTrustedDomainInfo
855 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
856 struct lsa_SetTrustedDomainInfo *r)
858 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
864 lsa_SetInfomrationTrustedDomain
866 static NTSTATUS dcesrv_lsa_SetInformationTrustedDomain(struct dcesrv_call_state *dce_call,
868 struct lsa_SetInformationTrustedDomain *r)
870 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
875 lsa_DeleteTrustedDomain
877 static NTSTATUS dcesrv_lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
878 struct lsa_DeleteTrustedDomain *r)
881 struct lsa_OpenTrustedDomain open;
882 struct lsa_DeleteObject delete;
883 struct dcesrv_handle *h;
885 open.in.handle = r->in.handle;
886 open.in.sid = r->in.dom_sid;
887 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
888 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
889 if (!open.out.trustdom_handle) {
890 return NT_STATUS_NO_MEMORY;
892 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
893 if (!NT_STATUS_IS_OK(status)) {
897 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
898 talloc_steal(mem_ctx, h);
900 delete.in.handle = open.out.trustdom_handle;
901 delete.out.handle = open.out.trustdom_handle;
902 status = dcesrv_lsa_DeleteObject(dce_call, mem_ctx, &delete);
903 if (!NT_STATUS_IS_OK(status)) {
909 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx,
910 struct ldb_message *msg,
911 struct lsa_TrustDomainInfoInfoEx *info_ex)
913 info_ex->domain_name.string
914 = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
915 info_ex->netbios_name.string
916 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
918 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
919 info_ex->trust_direction
920 = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
922 = ldb_msg_find_attr_as_int(msg, "trustType", 0);
923 info_ex->trust_attributes
924 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);
929 lsa_QueryTrustedDomainInfo
931 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
932 struct lsa_QueryTrustedDomainInfo *r)
934 struct dcesrv_handle *h;
935 struct lsa_trusted_domain_state *trusted_domain_state;
936 struct ldb_message *msg;
938 struct ldb_message **res;
939 const char *attrs[] = {
942 "securityIdentifier",
946 "msDs-supportedEncryptionTypes",
950 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
952 trusted_domain_state = h->data;
954 /* pull all the user attributes */
955 ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
956 trusted_domain_state->trusted_domain_dn, &res, attrs);
958 return NT_STATUS_INTERNAL_DB_CORRUPTION;
962 r->out.info = talloc(mem_ctx, union lsa_TrustedDomainInfo);
964 return NT_STATUS_NO_MEMORY;
966 switch (r->in.level) {
967 case LSA_TRUSTED_DOMAIN_INFO_NAME:
968 r->out.info->name.netbios_name.string
969 = samdb_result_string(msg, "flatname", NULL);
971 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
972 r->out.info->posix_offset.posix_offset
973 = samdb_result_uint(msg, "posixOffset", 0);
975 #if 0 /* Win2k3 doesn't implement this */
976 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
977 r->out.info->info_basic.netbios_name.string
978 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
979 r->out.info->info_basic.sid
980 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
983 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
984 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->info_ex);
986 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
987 ZERO_STRUCT(r->out.info->full_info);
988 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->full_info.info_ex);
990 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
991 ZERO_STRUCT(r->out.info->info2_internal);
992 r->out.info->info2_internal.posix_offset.posix_offset
993 = samdb_result_uint(msg, "posixOffset", 0);
994 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->info2_internal.info_ex);
996 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES:
997 r->out.info->enc_types.enc_types
998 = samdb_result_uint(msg, "msDs-supportedEncryptionTypes", KERB_ENCTYPE_RC4_HMAC_MD5);
1001 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
1002 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
1003 /* oops, we don't want to return the info after all */
1004 talloc_free(r->out.info);
1006 return NT_STATUS_INVALID_PARAMETER;
1008 /* oops, we don't want to return the info after all */
1009 talloc_free(r->out.info);
1011 return NT_STATUS_INVALID_INFO_CLASS;
1014 return NT_STATUS_OK;
1019 lsa_QueryTrustedDomainInfoBySid
1021 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1022 struct lsa_QueryTrustedDomainInfoBySid *r)
1025 struct lsa_OpenTrustedDomain open;
1026 struct lsa_QueryTrustedDomainInfo query;
1027 struct dcesrv_handle *h;
1028 open.in.handle = r->in.handle;
1029 open.in.sid = r->in.dom_sid;
1030 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1031 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1032 if (!open.out.trustdom_handle) {
1033 return NT_STATUS_NO_MEMORY;
1035 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
1036 if (!NT_STATUS_IS_OK(status)) {
1040 /* Ensure this handle goes away at the end of this call */
1041 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1042 talloc_steal(mem_ctx, h);
1044 query.in.trustdom_handle = open.out.trustdom_handle;
1045 query.in.level = r->in.level;
1046 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1047 if (!NT_STATUS_IS_OK(status)) {
1051 r->out.info = query.out.info;
1052 return NT_STATUS_OK;
1056 lsa_SetTrustedDomainInfoByName
1058 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1059 TALLOC_CTX *mem_ctx,
1060 struct lsa_SetTrustedDomainInfoByName *r)
1062 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1066 lsa_QueryTrustedDomainInfoByName
1068 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1069 TALLOC_CTX *mem_ctx,
1070 struct lsa_QueryTrustedDomainInfoByName *r)
1073 struct lsa_OpenTrustedDomainByName open;
1074 struct lsa_QueryTrustedDomainInfo query;
1075 struct dcesrv_handle *h;
1076 open.in.handle = r->in.handle;
1077 open.in.name = r->in.trusted_domain;
1078 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1079 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1080 if (!open.out.trustdom_handle) {
1081 return NT_STATUS_NO_MEMORY;
1083 status = dcesrv_lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &open);
1084 if (!NT_STATUS_IS_OK(status)) {
1088 /* Ensure this handle goes away at the end of this call */
1089 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1090 talloc_steal(mem_ctx, h);
1092 query.in.trustdom_handle = open.out.trustdom_handle;
1093 query.in.level = r->in.level;
1094 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1095 if (!NT_STATUS_IS_OK(status)) {
1099 r->out.info = query.out.info;
1100 return NT_STATUS_OK;
1104 lsa_CloseTrustedDomainEx
1106 static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
1107 TALLOC_CTX *mem_ctx,
1108 struct lsa_CloseTrustedDomainEx *r)
1110 /* The result of a bad hair day from an IDL programmer? Not
1111 * implmented in Win2k3. You should always just lsa_Close
1113 return NT_STATUS_NOT_IMPLEMENTED;
1118 comparison function for sorting lsa_DomainInformation array
1120 static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
1122 return strcasecmp_m(e1->name.string, e2->name.string);
1128 static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1129 struct lsa_EnumTrustDom *r)
1131 struct dcesrv_handle *policy_handle;
1132 struct lsa_DomainInfo *entries;
1133 struct lsa_policy_state *policy_state;
1134 struct ldb_message **domains;
1135 const char *attrs[] = {
1137 "securityIdentifier",
1144 *r->out.resume_handle = 0;
1146 r->out.domains->domains = NULL;
1147 r->out.domains->count = 0;
1149 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1151 policy_state = policy_handle->data;
1153 /* search for all users in this domain. This could possibly be cached and
1154 resumed based on resume_key */
1155 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1156 "objectclass=trustedDomain");
1158 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1161 /* convert to lsa_TrustInformation format */
1162 entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
1164 return NT_STATUS_NO_MEMORY;
1166 for (i=0;i<count;i++) {
1167 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
1168 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
1171 /* sort the results by name */
1172 qsort(entries, count, sizeof(*entries),
1173 (comparison_fn_t)compare_DomainInfo);
1175 if (*r->in.resume_handle >= count) {
1176 *r->out.resume_handle = -1;
1178 return NT_STATUS_NO_MORE_ENTRIES;
1181 /* return the rest, limit by max_size. Note that we
1182 use the w2k3 element size value of 60 */
1183 r->out.domains->count = count - *r->in.resume_handle;
1184 r->out.domains->count = MIN(r->out.domains->count,
1185 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
1187 r->out.domains->domains = entries + *r->in.resume_handle;
1188 r->out.domains->count = r->out.domains->count;
1190 if (r->out.domains->count < count - *r->in.resume_handle) {
1191 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1192 return STATUS_MORE_ENTRIES;
1195 return NT_STATUS_OK;
1199 comparison function for sorting lsa_DomainInformation array
1201 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
1203 return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
1207 lsa_EnumTrustedDomainsEx
1209 static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1210 struct lsa_EnumTrustedDomainsEx *r)
1212 struct dcesrv_handle *policy_handle;
1213 struct lsa_TrustDomainInfoInfoEx *entries;
1214 struct lsa_policy_state *policy_state;
1215 struct ldb_message **domains;
1216 const char *attrs[] = {
1219 "securityIdentifier",
1229 *r->out.resume_handle = 0;
1231 r->out.domains->domains = NULL;
1232 r->out.domains->count = 0;
1234 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1236 policy_state = policy_handle->data;
1238 /* search for all users in this domain. This could possibly be cached and
1239 resumed based on resume_key */
1240 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1241 "objectclass=trustedDomain");
1243 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1246 /* convert to lsa_DomainInformation format */
1247 entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
1249 return NT_STATUS_NO_MEMORY;
1251 for (i=0;i<count;i++) {
1252 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
1253 if (!NT_STATUS_IS_OK(nt_status)) {
1258 /* sort the results by name */
1259 qsort(entries, count, sizeof(*entries),
1260 (comparison_fn_t)compare_TrustDomainInfoInfoEx);
1262 if (*r->in.resume_handle >= count) {
1263 *r->out.resume_handle = -1;
1265 return NT_STATUS_NO_MORE_ENTRIES;
1268 /* return the rest, limit by max_size. Note that we
1269 use the w2k3 element size value of 60 */
1270 r->out.domains->count = count - *r->in.resume_handle;
1271 r->out.domains->count = MIN(r->out.domains->count,
1272 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
1274 r->out.domains->domains = entries + *r->in.resume_handle;
1275 r->out.domains->count = r->out.domains->count;
1277 if (r->out.domains->count < count - *r->in.resume_handle) {
1278 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1279 return STATUS_MORE_ENTRIES;
1282 return NT_STATUS_OK;
1289 static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1290 struct lsa_OpenAccount *r)
1292 struct dcesrv_handle *h, *ah;
1293 struct lsa_policy_state *state;
1294 struct lsa_account_state *astate;
1296 ZERO_STRUCTP(r->out.acct_handle);
1298 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1302 astate = talloc(dce_call->conn, struct lsa_account_state);
1303 if (astate == NULL) {
1304 return NT_STATUS_NO_MEMORY;
1307 astate->account_sid = dom_sid_dup(astate, r->in.sid);
1308 if (astate->account_sid == NULL) {
1309 talloc_free(astate);
1310 return NT_STATUS_NO_MEMORY;
1313 astate->policy = talloc_reference(astate, state);
1314 astate->access_mask = r->in.access_mask;
1316 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
1318 talloc_free(astate);
1319 return NT_STATUS_NO_MEMORY;
1322 ah->data = talloc_steal(ah, astate);
1324 *r->out.acct_handle = ah->wire_handle;
1326 return NT_STATUS_OK;
1331 lsa_EnumPrivsAccount
1333 static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
1334 TALLOC_CTX *mem_ctx,
1335 struct lsa_EnumPrivsAccount *r)
1337 struct dcesrv_handle *h;
1338 struct lsa_account_state *astate;
1340 struct ldb_message **res;
1341 const char * const attrs[] = { "privilege", NULL};
1342 struct ldb_message_element *el;
1345 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1349 r->out.privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
1350 r->out.privs->count = 0;
1351 r->out.privs->unknown = 0;
1352 r->out.privs->set = NULL;
1354 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
1355 if (sidstr == NULL) {
1356 return NT_STATUS_NO_MEMORY;
1359 ret = gendb_search(astate->policy->sam_ldb, mem_ctx, NULL, &res, attrs,
1360 "objectSid=%s", sidstr);
1362 return NT_STATUS_OK;
1365 el = ldb_msg_find_element(res[0], "privilege");
1366 if (el == NULL || el->num_values == 0) {
1367 return NT_STATUS_OK;
1370 r->out.privs->set = talloc_array(r->out.privs,
1371 struct lsa_LUIDAttribute, el->num_values);
1372 if (r->out.privs->set == NULL) {
1373 return NT_STATUS_NO_MEMORY;
1376 for (i=0;i<el->num_values;i++) {
1377 int id = sec_privilege_id((const char *)el->values[i].data);
1379 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1381 r->out.privs->set[i].attribute = 0;
1382 r->out.privs->set[i].luid.low = id;
1383 r->out.privs->set[i].luid.high = 0;
1386 r->out.privs->count = el->num_values;
1388 return NT_STATUS_OK;
1392 lsa_EnumAccountRights
1394 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
1395 TALLOC_CTX *mem_ctx,
1396 struct lsa_EnumAccountRights *r)
1398 struct dcesrv_handle *h;
1399 struct lsa_policy_state *state;
1401 struct ldb_message **res;
1402 const char * const attrs[] = { "privilege", NULL};
1404 struct ldb_message_element *el;
1406 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1410 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
1411 if (sidstr == NULL) {
1412 return NT_STATUS_NO_MEMORY;
1415 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
1416 "(&(objectSid=%s)(privilege=*))", sidstr);
1418 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1421 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1424 DEBUG(3, ("searching for account rights for SID: %s failed: %s",
1425 dom_sid_string(mem_ctx, r->in.sid),
1426 ldb_errstring(state->sam_ldb)));
1427 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1430 el = ldb_msg_find_element(res[0], "privilege");
1431 if (el == NULL || el->num_values == 0) {
1432 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1435 r->out.rights->count = el->num_values;
1436 r->out.rights->names = talloc_array(r->out.rights,
1437 struct lsa_StringLarge, r->out.rights->count);
1438 if (r->out.rights->names == NULL) {
1439 return NT_STATUS_NO_MEMORY;
1442 for (i=0;i<el->num_values;i++) {
1443 r->out.rights->names[i].string = (const char *)el->values[i].data;
1446 return NT_STATUS_OK;
1452 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
1454 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
1455 TALLOC_CTX *mem_ctx,
1456 struct lsa_policy_state *state,
1458 struct dom_sid *sid,
1459 const struct lsa_RightSet *rights)
1462 struct ldb_message *msg;
1463 struct ldb_message_element *el;
1465 struct lsa_EnumAccountRights r2;
1467 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, sid);
1468 if (sidstr == NULL) {
1469 return NT_STATUS_NO_MEMORY;
1472 msg = ldb_msg_new(mem_ctx);
1474 return NT_STATUS_NO_MEMORY;
1477 msg->dn = samdb_search_dn(state->sam_ldb, mem_ctx,
1478 NULL, "objectSid=%s", sidstr);
1479 if (msg->dn == NULL) {
1481 if (ldb_flag == LDB_FLAG_MOD_DELETE) {
1482 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1484 status = samdb_create_foreign_security_principal(state->sam_ldb, mem_ctx,
1486 if (!NT_STATUS_IS_OK(status)) {
1489 return NT_STATUS_NO_SUCH_USER;
1492 if (ldb_msg_add_empty(msg, "privilege", ldb_flag, NULL)) {
1493 return NT_STATUS_NO_MEMORY;
1496 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1499 r2.in.handle = &state->handle->wire_handle;
1501 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
1503 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1504 if (!NT_STATUS_IS_OK(status)) {
1505 ZERO_STRUCTP(r2.out.rights);
1509 for (i=0;i<rights->count;i++) {
1510 if (sec_privilege_id(rights->names[i].string) == -1) {
1511 return NT_STATUS_NO_SUCH_PRIVILEGE;
1514 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1516 for (j=0;j<r2.out.rights->count;j++) {
1517 if (strcasecmp_m(r2.out.rights->names[j].string,
1518 rights->names[i].string) == 0) {
1522 if (j != r2.out.rights->count) continue;
1525 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
1526 if (ret != LDB_SUCCESS) {
1527 return NT_STATUS_NO_MEMORY;
1531 el = ldb_msg_find_element(msg, "privilege");
1533 return NT_STATUS_OK;
1536 ret = ldb_modify(state->sam_ldb, msg);
1538 if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1539 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1541 DEBUG(3, ("Could not %s attributes from %s: %s",
1542 ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add",
1543 ldb_dn_get_linearized(msg->dn), ldb_errstring(state->sam_ldb)));
1544 return NT_STATUS_UNEXPECTED_IO_ERROR;
1547 return NT_STATUS_OK;
1551 lsa_AddPrivilegesToAccount
1553 static NTSTATUS dcesrv_lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1554 struct lsa_AddPrivilegesToAccount *r)
1556 struct lsa_RightSet rights;
1557 struct dcesrv_handle *h;
1558 struct lsa_account_state *astate;
1561 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1565 rights.count = r->in.privs->count;
1566 rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
1567 if (rights.names == NULL) {
1568 return NT_STATUS_NO_MEMORY;
1570 for (i=0;i<rights.count;i++) {
1571 int id = r->in.privs->set[i].luid.low;
1572 if (r->in.privs->set[i].luid.high) {
1573 return NT_STATUS_NO_SUCH_PRIVILEGE;
1575 rights.names[i].string = sec_privilege_name(id);
1576 if (rights.names[i].string == NULL) {
1577 return NT_STATUS_NO_SUCH_PRIVILEGE;
1581 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1582 LDB_FLAG_MOD_ADD, astate->account_sid,
1588 lsa_RemovePrivilegesFromAccount
1590 static NTSTATUS dcesrv_lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1591 struct lsa_RemovePrivilegesFromAccount *r)
1593 struct lsa_RightSet *rights;
1594 struct dcesrv_handle *h;
1595 struct lsa_account_state *astate;
1598 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1602 rights = talloc(mem_ctx, struct lsa_RightSet);
1604 if (r->in.remove_all == 1 &&
1605 r->in.privs == NULL) {
1606 struct lsa_EnumAccountRights r2;
1609 r2.in.handle = &astate->policy->handle->wire_handle;
1610 r2.in.sid = astate->account_sid;
1611 r2.out.rights = rights;
1613 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1614 if (!NT_STATUS_IS_OK(status)) {
1618 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1619 LDB_FLAG_MOD_DELETE, astate->account_sid,
1623 if (r->in.remove_all != 0) {
1624 return NT_STATUS_INVALID_PARAMETER;
1627 rights->count = r->in.privs->count;
1628 rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
1629 if (rights->names == NULL) {
1630 return NT_STATUS_NO_MEMORY;
1632 for (i=0;i<rights->count;i++) {
1633 int id = r->in.privs->set[i].luid.low;
1634 if (r->in.privs->set[i].luid.high) {
1635 return NT_STATUS_NO_SUCH_PRIVILEGE;
1637 rights->names[i].string = sec_privilege_name(id);
1638 if (rights->names[i].string == NULL) {
1639 return NT_STATUS_NO_SUCH_PRIVILEGE;
1643 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1644 LDB_FLAG_MOD_DELETE, astate->account_sid,
1650 lsa_GetQuotasForAccount
1652 static NTSTATUS dcesrv_lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1653 struct lsa_GetQuotasForAccount *r)
1655 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1660 lsa_SetQuotasForAccount
1662 static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1663 struct lsa_SetQuotasForAccount *r)
1665 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1670 lsa_GetSystemAccessAccount
1672 static NTSTATUS dcesrv_lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1673 struct lsa_GetSystemAccessAccount *r)
1675 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1680 lsa_SetSystemAccessAccount
1682 static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1683 struct lsa_SetSystemAccessAccount *r)
1685 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1692 static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1693 struct lsa_CreateSecret *r)
1695 struct dcesrv_handle *policy_handle;
1696 struct lsa_policy_state *policy_state;
1697 struct lsa_secret_state *secret_state;
1698 struct dcesrv_handle *handle;
1699 struct ldb_message **msgs, *msg;
1701 const char *attrs[] = {
1709 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1710 ZERO_STRUCTP(r->out.sec_handle);
1712 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
1714 case SECURITY_SYSTEM:
1715 case SECURITY_ADMINISTRATOR:
1718 /* Users and annonymous are not allowed create secrets */
1719 return NT_STATUS_ACCESS_DENIED;
1722 policy_state = policy_handle->data;
1724 if (!r->in.name.string) {
1725 return NT_STATUS_INVALID_PARAMETER;
1728 secret_state = talloc(mem_ctx, struct lsa_secret_state);
1729 if (!secret_state) {
1730 return NT_STATUS_NO_MEMORY;
1732 secret_state->policy = policy_state;
1734 msg = ldb_msg_new(mem_ctx);
1736 return NT_STATUS_NO_MEMORY;
1739 if (strncmp("G$", r->in.name.string, 2) == 0) {
1741 name = &r->in.name.string[2];
1742 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
1743 secret_state->global = true;
1745 if (strlen(name) < 1) {
1746 return NT_STATUS_INVALID_PARAMETER;
1749 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
1750 /* search for the secret record */
1751 ret = gendb_search(secret_state->sam_ldb,
1752 mem_ctx, policy_state->system_dn, &msgs, attrs,
1753 "(&(cn=%s)(objectclass=secret))",
1756 return NT_STATUS_OBJECT_NAME_COLLISION;
1760 DEBUG(0,("Failure searching for CN=%s: %s\n",
1761 name2, ldb_errstring(secret_state->sam_ldb)));
1762 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1765 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
1766 if (!name2 || ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
1767 return NT_STATUS_NO_MEMORY;
1770 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
1773 secret_state->global = false;
1775 name = r->in.name.string;
1776 if (strlen(name) < 1) {
1777 return NT_STATUS_INVALID_PARAMETER;
1780 secret_state->sam_ldb = talloc_reference(secret_state,
1781 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
1782 /* search for the secret record */
1783 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
1784 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
1786 "(&(cn=%s)(objectclass=secret))",
1787 ldb_binary_encode_string(mem_ctx, name));
1789 return NT_STATUS_OBJECT_NAME_COLLISION;
1793 DEBUG(0,("Failure searching for CN=%s: %s\n",
1794 name, ldb_errstring(secret_state->sam_ldb)));
1795 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1798 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name);
1799 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
1802 /* pull in all the template attributes. Note this is always from the global samdb */
1803 ret = samdb_copy_template(secret_state->policy->sam_ldb, msg,
1806 DEBUG(0,("Failed to load TemplateSecret from samdb: %s\n",
1808 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1811 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
1813 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
1815 /* create the secret */
1816 ret = ldb_add(secret_state->sam_ldb, msg);
1818 DEBUG(0,("Failed to create secret record %s: %s\n",
1819 ldb_dn_get_linearized(msg->dn),
1820 ldb_errstring(secret_state->sam_ldb)));
1821 return NT_STATUS_ACCESS_DENIED;
1824 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
1826 return NT_STATUS_NO_MEMORY;
1829 handle->data = talloc_steal(handle, secret_state);
1831 secret_state->access_mask = r->in.access_mask;
1832 secret_state->policy = talloc_reference(secret_state, policy_state);
1834 *r->out.sec_handle = handle->wire_handle;
1836 return NT_STATUS_OK;
1843 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1844 struct lsa_OpenSecret *r)
1846 struct dcesrv_handle *policy_handle;
1848 struct lsa_policy_state *policy_state;
1849 struct lsa_secret_state *secret_state;
1850 struct dcesrv_handle *handle;
1851 struct ldb_message **msgs;
1852 const char *attrs[] = {
1860 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1861 ZERO_STRUCTP(r->out.sec_handle);
1862 policy_state = policy_handle->data;
1864 if (!r->in.name.string) {
1865 return NT_STATUS_INVALID_PARAMETER;
1868 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
1870 case SECURITY_SYSTEM:
1871 case SECURITY_ADMINISTRATOR:
1874 /* Users and annonymous are not allowed to access secrets */
1875 return NT_STATUS_ACCESS_DENIED;
1878 secret_state = talloc(mem_ctx, struct lsa_secret_state);
1879 if (!secret_state) {
1880 return NT_STATUS_NO_MEMORY;
1882 secret_state->policy = policy_state;
1884 if (strncmp("G$", r->in.name.string, 2) == 0) {
1885 name = &r->in.name.string[2];
1886 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
1887 secret_state->global = true;
1889 if (strlen(name) < 1) {
1890 return NT_STATUS_INVALID_PARAMETER;
1893 /* search for the secret record */
1894 ret = gendb_search(secret_state->sam_ldb,
1895 mem_ctx, policy_state->system_dn, &msgs, attrs,
1896 "(&(cn=%s Secret)(objectclass=secret))",
1897 ldb_binary_encode_string(mem_ctx, name));
1899 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1903 DEBUG(0,("Found %d records matching DN %s\n", ret,
1904 ldb_dn_get_linearized(policy_state->system_dn)));
1905 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1909 secret_state->global = false;
1910 secret_state->sam_ldb = talloc_reference(secret_state,
1911 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
1913 name = r->in.name.string;
1914 if (strlen(name) < 1) {
1915 return NT_STATUS_INVALID_PARAMETER;
1918 /* search for the secret record */
1919 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
1920 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
1922 "(&(cn=%s)(objectclass=secret))",
1923 ldb_binary_encode_string(mem_ctx, name));
1925 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1929 DEBUG(0,("Found %d records matching CN=%s\n",
1930 ret, ldb_binary_encode_string(mem_ctx, name)));
1931 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1935 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
1937 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
1939 return NT_STATUS_NO_MEMORY;
1942 handle->data = talloc_steal(handle, secret_state);
1944 secret_state->access_mask = r->in.access_mask;
1945 secret_state->policy = talloc_reference(secret_state, policy_state);
1947 *r->out.sec_handle = handle->wire_handle;
1949 return NT_STATUS_OK;
1956 static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1957 struct lsa_SetSecret *r)
1960 struct dcesrv_handle *h;
1961 struct lsa_secret_state *secret_state;
1962 struct ldb_message *msg;
1963 DATA_BLOB session_key;
1964 DATA_BLOB crypt_secret, secret;
1967 NTSTATUS status = NT_STATUS_OK;
1969 struct timeval now = timeval_current();
1970 NTTIME nt_now = timeval_to_nttime(&now);
1972 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
1974 secret_state = h->data;
1976 msg = ldb_msg_new(mem_ctx);
1978 return NT_STATUS_NO_MEMORY;
1981 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
1983 return NT_STATUS_NO_MEMORY;
1985 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
1986 if (!NT_STATUS_IS_OK(status)) {
1990 if (r->in.old_val) {
1992 crypt_secret.data = r->in.old_val->data;
1993 crypt_secret.length = r->in.old_val->size;
1995 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
1996 if (!NT_STATUS_IS_OK(status)) {
2000 val.data = secret.data;
2001 val.length = secret.length;
2004 if (samdb_msg_add_value(secret_state->sam_ldb,
2005 mem_ctx, msg, "priorValue", &val) != 0) {
2006 return NT_STATUS_NO_MEMORY;
2009 /* set old value mtime */
2010 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2011 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
2012 return NT_STATUS_NO_MEMORY;
2015 if (!r->in.new_val) {
2016 /* set old value mtime */
2017 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2018 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2019 return NT_STATUS_NO_MEMORY;
2021 if (samdb_msg_add_delete(secret_state->sam_ldb,
2022 mem_ctx, msg, "currentValue")) {
2023 return NT_STATUS_NO_MEMORY;
2028 if (r->in.new_val) {
2030 crypt_secret.data = r->in.new_val->data;
2031 crypt_secret.length = r->in.new_val->size;
2033 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2034 if (!NT_STATUS_IS_OK(status)) {
2038 val.data = secret.data;
2039 val.length = secret.length;
2042 if (samdb_msg_add_value(secret_state->sam_ldb,
2043 mem_ctx, msg, "currentValue", &val) != 0) {
2044 return NT_STATUS_NO_MEMORY;
2047 /* set new value mtime */
2048 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2049 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2050 return NT_STATUS_NO_MEMORY;
2053 /* If the old value is not set, then migrate the
2054 * current value to the old value */
2055 if (!r->in.old_val) {
2056 const struct ldb_val *new_val;
2057 NTTIME last_set_time;
2058 struct ldb_message **res;
2059 const char *attrs[] = {
2065 /* search for the secret record */
2066 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
2067 secret_state->secret_dn, &res, attrs);
2069 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2073 DEBUG(0,("Found %d records matching dn=%s\n", ret,
2074 ldb_dn_get_linearized(secret_state->secret_dn)));
2075 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2078 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2079 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2083 if (samdb_msg_add_value(secret_state->sam_ldb,
2084 mem_ctx, msg, "priorValue",
2086 return NT_STATUS_NO_MEMORY;
2090 /* set new value mtime */
2091 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2092 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2093 mem_ctx, msg, "priorSetTime", last_set_time) != 0) {
2094 return NT_STATUS_NO_MEMORY;
2100 /* modify the samdb record */
2101 ret = samdb_replace(secret_state->sam_ldb, mem_ctx, msg);
2103 /* we really need samdb.c to return NTSTATUS */
2104 return NT_STATUS_UNSUCCESSFUL;
2107 return NT_STATUS_OK;
2114 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2115 struct lsa_QuerySecret *r)
2117 struct dcesrv_handle *h;
2118 struct lsa_secret_state *secret_state;
2119 struct ldb_message *msg;
2120 DATA_BLOB session_key;
2121 DATA_BLOB crypt_secret, secret;
2123 struct ldb_message **res;
2124 const char *attrs[] = {
2134 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2136 /* Ensure user is permitted to read this... */
2137 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2139 case SECURITY_SYSTEM:
2140 case SECURITY_ADMINISTRATOR:
2143 /* Users and annonymous are not allowed to read secrets */
2144 return NT_STATUS_ACCESS_DENIED;
2147 secret_state = h->data;
2149 /* pull all the user attributes */
2150 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2151 secret_state->secret_dn, &res, attrs);
2153 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2157 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2158 if (!NT_STATUS_IS_OK(nt_status)) {
2162 if (r->in.old_val) {
2163 const struct ldb_val *prior_val;
2164 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2165 if (!r->out.old_val) {
2166 return NT_STATUS_NO_MEMORY;
2168 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
2170 if (prior_val && prior_val->length) {
2171 secret.data = prior_val->data;
2172 secret.length = prior_val->length;
2175 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2176 if (!crypt_secret.length) {
2177 return NT_STATUS_NO_MEMORY;
2179 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2180 if (!r->out.old_val->buf) {
2181 return NT_STATUS_NO_MEMORY;
2183 r->out.old_val->buf->size = crypt_secret.length;
2184 r->out.old_val->buf->length = crypt_secret.length;
2185 r->out.old_val->buf->data = crypt_secret.data;
2189 if (r->in.old_mtime) {
2190 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2191 if (!r->out.old_mtime) {
2192 return NT_STATUS_NO_MEMORY;
2194 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
2197 if (r->in.new_val) {
2198 const struct ldb_val *new_val;
2199 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2200 if (!r->out.new_val) {
2201 return NT_STATUS_NO_MEMORY;
2204 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2206 if (new_val && new_val->length) {
2207 secret.data = new_val->data;
2208 secret.length = new_val->length;
2211 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2212 if (!crypt_secret.length) {
2213 return NT_STATUS_NO_MEMORY;
2215 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2216 if (!r->out.new_val->buf) {
2217 return NT_STATUS_NO_MEMORY;
2219 r->out.new_val->buf->length = crypt_secret.length;
2220 r->out.new_val->buf->size = crypt_secret.length;
2221 r->out.new_val->buf->data = crypt_secret.data;
2225 if (r->in.new_mtime) {
2226 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2227 if (!r->out.new_mtime) {
2228 return NT_STATUS_NO_MEMORY;
2230 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2233 return NT_STATUS_OK;
2240 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
2241 TALLOC_CTX *mem_ctx,
2242 struct lsa_LookupPrivValue *r)
2244 struct dcesrv_handle *h;
2245 struct lsa_policy_state *state;
2248 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2252 id = sec_privilege_id(r->in.name->string);
2254 return NT_STATUS_NO_SUCH_PRIVILEGE;
2257 r->out.luid->low = id;
2258 r->out.luid->high = 0;
2260 return NT_STATUS_OK;
2267 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
2268 TALLOC_CTX *mem_ctx,
2269 struct lsa_LookupPrivName *r)
2271 struct dcesrv_handle *h;
2272 struct lsa_policy_state *state;
2273 const char *privname;
2275 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2279 if (r->in.luid->high != 0) {
2280 return NT_STATUS_NO_SUCH_PRIVILEGE;
2283 privname = sec_privilege_name(r->in.luid->low);
2284 if (privname == NULL) {
2285 return NT_STATUS_NO_SUCH_PRIVILEGE;
2288 r->out.name = talloc(mem_ctx, struct lsa_StringLarge);
2289 if (r->out.name == NULL) {
2290 return NT_STATUS_NO_MEMORY;
2292 r->out.name->string = privname;
2294 return NT_STATUS_OK;
2299 lsa_LookupPrivDisplayName
2301 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
2302 TALLOC_CTX *mem_ctx,
2303 struct lsa_LookupPrivDisplayName *r)
2305 struct dcesrv_handle *h;
2306 struct lsa_policy_state *state;
2309 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2313 id = sec_privilege_id(r->in.name->string);
2315 return NT_STATUS_NO_SUCH_PRIVILEGE;
2318 r->out.disp_name = talloc(mem_ctx, struct lsa_StringLarge);
2319 if (r->out.disp_name == NULL) {
2320 return NT_STATUS_NO_MEMORY;
2323 r->out.disp_name->string = sec_privilege_display_name(id, r->in.language_id);
2324 if (r->out.disp_name->string == NULL) {
2325 return NT_STATUS_INTERNAL_ERROR;
2328 return NT_STATUS_OK;
2333 lsa_EnumAccountsWithUserRight
2335 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
2336 TALLOC_CTX *mem_ctx,
2337 struct lsa_EnumAccountsWithUserRight *r)
2339 struct dcesrv_handle *h;
2340 struct lsa_policy_state *state;
2342 struct ldb_message **res;
2343 const char * const attrs[] = { "objectSid", NULL};
2344 const char *privname;
2346 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2350 if (r->in.name == NULL) {
2351 return NT_STATUS_NO_SUCH_PRIVILEGE;
2354 privname = r->in.name->string;
2355 if (sec_privilege_id(privname) == -1) {
2356 return NT_STATUS_NO_SUCH_PRIVILEGE;
2359 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
2360 "privilege=%s", privname);
2362 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2365 return NT_STATUS_NO_MORE_ENTRIES;
2368 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2369 if (r->out.sids->sids == NULL) {
2370 return NT_STATUS_NO_MEMORY;
2372 for (i=0;i<ret;i++) {
2373 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2374 res[i], "objectSid");
2375 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2377 r->out.sids->num_sids = ret;
2379 return NT_STATUS_OK;
2384 lsa_AddAccountRights
2386 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
2387 TALLOC_CTX *mem_ctx,
2388 struct lsa_AddAccountRights *r)
2390 struct dcesrv_handle *h;
2391 struct lsa_policy_state *state;
2393 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2397 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2399 r->in.sid, r->in.rights);
2404 lsa_RemoveAccountRights
2406 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
2407 TALLOC_CTX *mem_ctx,
2408 struct lsa_RemoveAccountRights *r)
2410 struct dcesrv_handle *h;
2411 struct lsa_policy_state *state;
2413 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2417 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2418 LDB_FLAG_MOD_DELETE,
2419 r->in.sid, r->in.rights);
2424 lsa_StorePrivateData
2426 static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2427 struct lsa_StorePrivateData *r)
2429 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2434 lsa_RetrievePrivateData
2436 static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2437 struct lsa_RetrievePrivateData *r)
2439 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2446 static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2447 struct lsa_GetUserName *r)
2449 NTSTATUS status = NT_STATUS_OK;
2450 const char *account_name;
2451 const char *authority_name;
2452 struct lsa_String *_account_name;
2453 struct lsa_StringPointer *_authority_name = NULL;
2455 /* this is what w2k3 does */
2456 r->out.account_name = r->in.account_name;
2457 r->out.authority_name = r->in.authority_name;
2459 if (r->in.account_name && r->in.account_name->string) {
2460 return NT_STATUS_INVALID_PARAMETER;
2463 if (r->in.authority_name &&
2464 r->in.authority_name->string &&
2465 r->in.authority_name->string->string) {
2466 return NT_STATUS_INVALID_PARAMETER;
2469 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
2470 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
2472 _account_name = talloc(mem_ctx, struct lsa_String);
2473 NT_STATUS_HAVE_NO_MEMORY(_account_name);
2474 _account_name->string = account_name;
2476 if (r->in.authority_name) {
2477 _authority_name = talloc(mem_ctx, struct lsa_StringPointer);
2478 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
2479 _authority_name->string = talloc(mem_ctx, struct lsa_String);
2480 NT_STATUS_HAVE_NO_MEMORY(_authority_name->string);
2481 _authority_name->string->string = authority_name;
2484 r->out.account_name = _account_name;
2485 r->out.authority_name = _authority_name;
2493 static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
2494 TALLOC_CTX *mem_ctx,
2495 struct lsa_SetInfoPolicy2 *r)
2497 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2501 lsa_QueryDomainInformationPolicy
2503 static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2504 TALLOC_CTX *mem_ctx,
2505 struct lsa_QueryDomainInformationPolicy *r)
2507 r->out.info = talloc(mem_ctx, union lsa_DomainInformationPolicy);
2509 return NT_STATUS_NO_MEMORY;
2512 switch (r->in.level) {
2513 case LSA_DOMAIN_INFO_POLICY_EFS:
2514 talloc_free(r->out.info);
2516 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2517 case LSA_DOMAIN_INFO_POLICY_KERBEROS:
2519 struct lsa_DomainInfoKerberos *k = &r->out.info->kerberos_info;
2520 struct smb_krb5_context *smb_krb5_context;
2521 int ret = smb_krb5_init_context(mem_ctx,
2522 dce_call->event_ctx,
2523 dce_call->conn->dce_ctx->lp_ctx,
2526 talloc_free(r->out.info);
2528 return NT_STATUS_INTERNAL_ERROR;
2530 k->enforce_restrictions = 0; /* FIXME, details missing from MS-LSAD 2.2.53 */
2531 k->service_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
2532 k->user_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
2533 k->user_tkt_renewaltime = 0; /* Need to find somewhere to store this, and query in KDC too */
2534 k->clock_skew = krb5_get_max_time_skew(smb_krb5_context->krb5_context);
2535 talloc_free(smb_krb5_context);
2536 return NT_STATUS_OK;
2539 talloc_free(r->out.info);
2541 return NT_STATUS_INVALID_INFO_CLASS;
2546 lsa_SetDomInfoPolicy
2548 static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2549 TALLOC_CTX *mem_ctx,
2550 struct lsa_SetDomainInformationPolicy *r)
2552 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2558 static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
2559 TALLOC_CTX *mem_ctx,
2560 struct lsa_TestCall *r)
2562 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2568 static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2569 struct lsa_CREDRWRITE *r)
2571 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2578 static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2579 struct lsa_CREDRREAD *r)
2581 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2588 static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2589 struct lsa_CREDRENUMERATE *r)
2591 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2596 lsa_CREDRWRITEDOMAINCREDENTIALS
2598 static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2599 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
2601 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2606 lsa_CREDRREADDOMAINCREDENTIALS
2608 static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2609 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
2611 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2618 static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2619 struct lsa_CREDRDELETE *r)
2621 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2626 lsa_CREDRGETTARGETINFO
2628 static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2629 struct lsa_CREDRGETTARGETINFO *r)
2631 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2636 lsa_CREDRPROFILELOADED
2638 static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2639 struct lsa_CREDRPROFILELOADED *r)
2641 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2646 lsa_CREDRGETSESSIONTYPES
2648 static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2649 struct lsa_CREDRGETSESSIONTYPES *r)
2651 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2656 lsa_LSARREGISTERAUDITEVENT
2658 static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2659 struct lsa_LSARREGISTERAUDITEVENT *r)
2661 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2666 lsa_LSARGENAUDITEVENT
2668 static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2669 struct lsa_LSARGENAUDITEVENT *r)
2671 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2676 lsa_LSARUNREGISTERAUDITEVENT
2678 static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2679 struct lsa_LSARUNREGISTERAUDITEVENT *r)
2681 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2686 lsa_lsaRQueryForestTrustInformation
2688 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2689 struct lsa_lsaRQueryForestTrustInformation *r)
2691 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2696 lsa_LSARSETFORESTTRUSTINFORMATION
2698 static NTSTATUS dcesrv_lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2699 struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
2701 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2708 static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2709 struct lsa_CREDRRENAME *r)
2711 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2717 lsa_LSAROPENPOLICYSCE
2719 static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2720 struct lsa_LSAROPENPOLICYSCE *r)
2722 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2727 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
2729 static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2730 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
2732 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2737 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
2739 static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2740 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
2742 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2747 lsa_LSARADTREPORTSECURITYEVENT
2749 static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2750 struct lsa_LSARADTREPORTSECURITYEVENT *r)
2752 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2756 /* include the generated boilerplate */
2757 #include "librpc/gen_ndr/ndr_lsa_s.c"
2761 /*****************************************
2762 NOTE! The remaining calls below were
2763 removed in w2k3, so the DCESRV_FAULT()
2764 replies are the correct implementation. Do
2765 not try and fill these in with anything else
2766 ******************************************/
2769 dssetup_DsRoleDnsNameToFlatName
2771 static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2772 struct dssetup_DsRoleDnsNameToFlatName *r)
2774 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2779 dssetup_DsRoleDcAsDc
2781 static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2782 struct dssetup_DsRoleDcAsDc *r)
2784 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2789 dssetup_DsRoleDcAsReplica
2791 static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2792 struct dssetup_DsRoleDcAsReplica *r)
2794 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2799 dssetup_DsRoleDemoteDc
2801 static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2802 struct dssetup_DsRoleDemoteDc *r)
2804 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2809 dssetup_DsRoleGetDcOperationProgress
2811 static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2812 struct dssetup_DsRoleGetDcOperationProgress *r)
2814 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2819 dssetup_DsRoleGetDcOperationResults
2821 static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2822 struct dssetup_DsRoleGetDcOperationResults *r)
2824 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2829 dssetup_DsRoleCancel
2831 static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2832 struct dssetup_DsRoleCancel *r)
2834 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2839 dssetup_DsRoleServerSaveStateForUpgrade
2841 static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2842 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
2844 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2849 dssetup_DsRoleUpgradeDownlevelServer
2851 static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2852 struct dssetup_DsRoleUpgradeDownlevelServer *r)
2854 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2859 dssetup_DsRoleAbortDownlevelServerUpgrade
2861 static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2862 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
2864 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2868 /* include the generated boilerplate */
2869 #include "librpc/gen_ndr/ndr_dssetup_s.c"
2871 NTSTATUS dcerpc_server_lsa_init(void)
2875 ret = dcerpc_server_dssetup_init();
2876 if (!NT_STATUS_IS_OK(ret)) {
2879 ret = dcerpc_server_lsarpc_init();
2880 if (!NT_STATUS_IS_OK(ret)) {