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 samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustType", LSA_TRUST_TYPE_DOWNLEVEL);
678 samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustAttributes", 0);
680 samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustDirection", LSA_TRUST_DIRECTION_OUTBOUND);
682 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
684 /* create the trusted_domain */
685 ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg);
689 case LDB_ERR_ENTRY_ALREADY_EXISTS:
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_DOMAIN_EXISTS;
695 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
696 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
697 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
698 ldb_dn_get_linearized(msg->dn),
699 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
700 return NT_STATUS_ACCESS_DENIED;
702 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
703 DEBUG(0,("Failed to create user record %s: %s\n",
704 ldb_dn_get_linearized(msg->dn),
705 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
706 return NT_STATUS_INTERNAL_DB_CORRUPTION;
709 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
711 return NT_STATUS_NO_MEMORY;
714 handle->data = talloc_steal(handle, trusted_domain_state);
716 trusted_domain_state->access_mask = r->in.access_mask;
717 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
719 *r->out.trustdom_handle = handle->wire_handle;
725 lsa_OpenTrustedDomain
727 static NTSTATUS dcesrv_lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
728 struct lsa_OpenTrustedDomain *r)
730 struct dcesrv_handle *policy_handle;
732 struct lsa_policy_state *policy_state;
733 struct lsa_trusted_domain_state *trusted_domain_state;
734 struct dcesrv_handle *handle;
735 struct ldb_message **msgs;
736 const char *attrs[] = {
740 const char *sid_string;
743 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
744 ZERO_STRUCTP(r->out.trustdom_handle);
745 policy_state = policy_handle->data;
747 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
748 if (!trusted_domain_state) {
749 return NT_STATUS_NO_MEMORY;
751 trusted_domain_state->policy = policy_state;
753 sid_string = dom_sid_string(mem_ctx, r->in.sid);
755 return NT_STATUS_NO_MEMORY;
758 /* search for the trusted_domain record */
759 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
760 mem_ctx, policy_state->system_dn, &msgs, attrs,
761 "(&(securityIdentifier=%s)(objectclass=trustedDomain))",
764 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
768 DEBUG(0,("Found %d records matching DN %s\n", ret,
769 ldb_dn_get_linearized(policy_state->system_dn)));
770 return NT_STATUS_INTERNAL_DB_CORRUPTION;
773 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
775 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
777 return NT_STATUS_NO_MEMORY;
780 handle->data = talloc_steal(handle, trusted_domain_state);
782 trusted_domain_state->access_mask = r->in.access_mask;
783 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
785 *r->out.trustdom_handle = handle->wire_handle;
792 lsa_OpenTrustedDomainByName
794 static NTSTATUS dcesrv_lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
796 struct lsa_OpenTrustedDomainByName *r)
798 struct dcesrv_handle *policy_handle;
800 struct lsa_policy_state *policy_state;
801 struct lsa_trusted_domain_state *trusted_domain_state;
802 struct dcesrv_handle *handle;
803 struct ldb_message **msgs;
804 const char *attrs[] = {
810 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
811 ZERO_STRUCTP(r->out.trustdom_handle);
812 policy_state = policy_handle->data;
814 if (!r->in.name.string) {
815 return NT_STATUS_INVALID_PARAMETER;
818 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
819 if (!trusted_domain_state) {
820 return NT_STATUS_NO_MEMORY;
822 trusted_domain_state->policy = policy_state;
824 /* search for the trusted_domain record */
825 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
826 mem_ctx, policy_state->system_dn, &msgs, attrs,
827 "(&(flatname=%s)(objectclass=trustedDomain))",
828 ldb_binary_encode_string(mem_ctx, r->in.name.string));
830 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
834 DEBUG(0,("Found %d records matching DN %s\n", ret,
835 ldb_dn_get_linearized(policy_state->system_dn)));
836 return NT_STATUS_INTERNAL_DB_CORRUPTION;
839 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
841 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
843 return NT_STATUS_NO_MEMORY;
846 handle->data = talloc_steal(handle, trusted_domain_state);
848 trusted_domain_state->access_mask = r->in.access_mask;
849 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
851 *r->out.trustdom_handle = handle->wire_handle;
859 lsa_SetTrustedDomainInfo
861 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
862 struct lsa_SetTrustedDomainInfo *r)
864 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
870 lsa_SetInfomrationTrustedDomain
872 static NTSTATUS dcesrv_lsa_SetInformationTrustedDomain(struct dcesrv_call_state *dce_call,
874 struct lsa_SetInformationTrustedDomain *r)
876 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
881 lsa_DeleteTrustedDomain
883 static NTSTATUS dcesrv_lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
884 struct lsa_DeleteTrustedDomain *r)
887 struct lsa_OpenTrustedDomain open;
888 struct lsa_DeleteObject delete;
889 struct dcesrv_handle *h;
891 open.in.handle = r->in.handle;
892 open.in.sid = r->in.dom_sid;
893 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
894 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
895 if (!open.out.trustdom_handle) {
896 return NT_STATUS_NO_MEMORY;
898 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
899 if (!NT_STATUS_IS_OK(status)) {
903 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
904 talloc_steal(mem_ctx, h);
906 delete.in.handle = open.out.trustdom_handle;
907 delete.out.handle = open.out.trustdom_handle;
908 status = dcesrv_lsa_DeleteObject(dce_call, mem_ctx, &delete);
909 if (!NT_STATUS_IS_OK(status)) {
915 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx,
916 struct ldb_message *msg,
917 struct lsa_TrustDomainInfoInfoEx *info_ex)
919 info_ex->domain_name.string
920 = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
921 info_ex->netbios_name.string
922 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
924 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
925 info_ex->trust_direction
926 = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
928 = ldb_msg_find_attr_as_int(msg, "trustType", 0);
929 info_ex->trust_attributes
930 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);
935 lsa_QueryTrustedDomainInfo
937 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
938 struct lsa_QueryTrustedDomainInfo *r)
940 struct dcesrv_handle *h;
941 struct lsa_trusted_domain_state *trusted_domain_state;
942 struct ldb_message *msg;
944 struct ldb_message **res;
945 const char *attrs[] = {
948 "securityIdentifier",
952 "msDs-supportedEncryptionTypes",
956 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
958 trusted_domain_state = h->data;
960 /* pull all the user attributes */
961 ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
962 trusted_domain_state->trusted_domain_dn, &res, attrs);
964 return NT_STATUS_INTERNAL_DB_CORRUPTION;
968 r->out.info = talloc(mem_ctx, union lsa_TrustedDomainInfo);
970 return NT_STATUS_NO_MEMORY;
972 switch (r->in.level) {
973 case LSA_TRUSTED_DOMAIN_INFO_NAME:
974 r->out.info->name.netbios_name.string
975 = samdb_result_string(msg, "flatname", NULL);
977 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
978 r->out.info->posix_offset.posix_offset
979 = samdb_result_uint(msg, "posixOffset", 0);
981 #if 0 /* Win2k3 doesn't implement this */
982 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
983 r->out.info->info_basic.netbios_name.string
984 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
985 r->out.info->info_basic.sid
986 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
989 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
990 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->info_ex);
992 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
993 ZERO_STRUCT(r->out.info->full_info);
994 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->full_info.info_ex);
996 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
997 ZERO_STRUCT(r->out.info->info2_internal);
998 r->out.info->info2_internal.posix_offset.posix_offset
999 = samdb_result_uint(msg, "posixOffset", 0);
1000 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->info2_internal.info_ex);
1002 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES:
1003 r->out.info->enc_types.enc_types
1004 = samdb_result_uint(msg, "msDs-supportedEncryptionTypes", KERB_ENCTYPE_RC4_HMAC_MD5);
1007 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
1008 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
1009 /* oops, we don't want to return the info after all */
1010 talloc_free(r->out.info);
1012 return NT_STATUS_INVALID_PARAMETER;
1014 /* oops, we don't want to return the info after all */
1015 talloc_free(r->out.info);
1017 return NT_STATUS_INVALID_INFO_CLASS;
1020 return NT_STATUS_OK;
1025 lsa_QueryTrustedDomainInfoBySid
1027 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1028 struct lsa_QueryTrustedDomainInfoBySid *r)
1031 struct lsa_OpenTrustedDomain open;
1032 struct lsa_QueryTrustedDomainInfo query;
1033 struct dcesrv_handle *h;
1034 open.in.handle = r->in.handle;
1035 open.in.sid = r->in.dom_sid;
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_OpenTrustedDomain(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_SetTrustedDomainInfoByName
1064 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1065 TALLOC_CTX *mem_ctx,
1066 struct lsa_SetTrustedDomainInfoByName *r)
1068 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1072 lsa_QueryTrustedDomainInfoByName
1074 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1075 TALLOC_CTX *mem_ctx,
1076 struct lsa_QueryTrustedDomainInfoByName *r)
1079 struct lsa_OpenTrustedDomainByName open;
1080 struct lsa_QueryTrustedDomainInfo query;
1081 struct dcesrv_handle *h;
1082 open.in.handle = r->in.handle;
1083 open.in.name = r->in.trusted_domain;
1084 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1085 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1086 if (!open.out.trustdom_handle) {
1087 return NT_STATUS_NO_MEMORY;
1089 status = dcesrv_lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &open);
1090 if (!NT_STATUS_IS_OK(status)) {
1094 /* Ensure this handle goes away at the end of this call */
1095 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1096 talloc_steal(mem_ctx, h);
1098 query.in.trustdom_handle = open.out.trustdom_handle;
1099 query.in.level = r->in.level;
1100 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1101 if (!NT_STATUS_IS_OK(status)) {
1105 r->out.info = query.out.info;
1106 return NT_STATUS_OK;
1110 lsa_CloseTrustedDomainEx
1112 static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
1113 TALLOC_CTX *mem_ctx,
1114 struct lsa_CloseTrustedDomainEx *r)
1116 /* The result of a bad hair day from an IDL programmer? Not
1117 * implmented in Win2k3. You should always just lsa_Close
1119 return NT_STATUS_NOT_IMPLEMENTED;
1124 comparison function for sorting lsa_DomainInformation array
1126 static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
1128 return strcasecmp_m(e1->name.string, e2->name.string);
1134 static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1135 struct lsa_EnumTrustDom *r)
1137 struct dcesrv_handle *policy_handle;
1138 struct lsa_DomainInfo *entries;
1139 struct lsa_policy_state *policy_state;
1140 struct ldb_message **domains;
1141 const char *attrs[] = {
1143 "securityIdentifier",
1150 *r->out.resume_handle = 0;
1152 r->out.domains->domains = NULL;
1153 r->out.domains->count = 0;
1155 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1157 policy_state = policy_handle->data;
1159 /* search for all users in this domain. This could possibly be cached and
1160 resumed based on resume_key */
1161 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1162 "objectclass=trustedDomain");
1164 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1167 /* convert to lsa_TrustInformation format */
1168 entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
1170 return NT_STATUS_NO_MEMORY;
1172 for (i=0;i<count;i++) {
1173 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
1174 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
1177 /* sort the results by name */
1178 qsort(entries, count, sizeof(*entries),
1179 (comparison_fn_t)compare_DomainInfo);
1181 if (*r->in.resume_handle >= count) {
1182 *r->out.resume_handle = -1;
1184 return NT_STATUS_NO_MORE_ENTRIES;
1187 /* return the rest, limit by max_size. Note that we
1188 use the w2k3 element size value of 60 */
1189 r->out.domains->count = count - *r->in.resume_handle;
1190 r->out.domains->count = MIN(r->out.domains->count,
1191 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
1193 r->out.domains->domains = entries + *r->in.resume_handle;
1194 r->out.domains->count = r->out.domains->count;
1196 if (r->out.domains->count < count - *r->in.resume_handle) {
1197 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1198 return STATUS_MORE_ENTRIES;
1201 return NT_STATUS_OK;
1205 comparison function for sorting lsa_DomainInformation array
1207 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
1209 return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
1213 lsa_EnumTrustedDomainsEx
1215 static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1216 struct lsa_EnumTrustedDomainsEx *r)
1218 struct dcesrv_handle *policy_handle;
1219 struct lsa_TrustDomainInfoInfoEx *entries;
1220 struct lsa_policy_state *policy_state;
1221 struct ldb_message **domains;
1222 const char *attrs[] = {
1225 "securityIdentifier",
1235 *r->out.resume_handle = 0;
1237 r->out.domains->domains = NULL;
1238 r->out.domains->count = 0;
1240 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1242 policy_state = policy_handle->data;
1244 /* search for all users in this domain. This could possibly be cached and
1245 resumed based on resume_key */
1246 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1247 "objectclass=trustedDomain");
1249 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1252 /* convert to lsa_DomainInformation format */
1253 entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
1255 return NT_STATUS_NO_MEMORY;
1257 for (i=0;i<count;i++) {
1258 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
1259 if (!NT_STATUS_IS_OK(nt_status)) {
1264 /* sort the results by name */
1265 qsort(entries, count, sizeof(*entries),
1266 (comparison_fn_t)compare_TrustDomainInfoInfoEx);
1268 if (*r->in.resume_handle >= count) {
1269 *r->out.resume_handle = -1;
1271 return NT_STATUS_NO_MORE_ENTRIES;
1274 /* return the rest, limit by max_size. Note that we
1275 use the w2k3 element size value of 60 */
1276 r->out.domains->count = count - *r->in.resume_handle;
1277 r->out.domains->count = MIN(r->out.domains->count,
1278 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
1280 r->out.domains->domains = entries + *r->in.resume_handle;
1281 r->out.domains->count = r->out.domains->count;
1283 if (r->out.domains->count < count - *r->in.resume_handle) {
1284 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1285 return STATUS_MORE_ENTRIES;
1288 return NT_STATUS_OK;
1295 static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1296 struct lsa_OpenAccount *r)
1298 struct dcesrv_handle *h, *ah;
1299 struct lsa_policy_state *state;
1300 struct lsa_account_state *astate;
1302 ZERO_STRUCTP(r->out.acct_handle);
1304 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1308 astate = talloc(dce_call->conn, struct lsa_account_state);
1309 if (astate == NULL) {
1310 return NT_STATUS_NO_MEMORY;
1313 astate->account_sid = dom_sid_dup(astate, r->in.sid);
1314 if (astate->account_sid == NULL) {
1315 talloc_free(astate);
1316 return NT_STATUS_NO_MEMORY;
1319 astate->policy = talloc_reference(astate, state);
1320 astate->access_mask = r->in.access_mask;
1322 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
1324 talloc_free(astate);
1325 return NT_STATUS_NO_MEMORY;
1328 ah->data = talloc_steal(ah, astate);
1330 *r->out.acct_handle = ah->wire_handle;
1332 return NT_STATUS_OK;
1337 lsa_EnumPrivsAccount
1339 static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
1340 TALLOC_CTX *mem_ctx,
1341 struct lsa_EnumPrivsAccount *r)
1343 struct dcesrv_handle *h;
1344 struct lsa_account_state *astate;
1346 struct ldb_message **res;
1347 const char * const attrs[] = { "privilege", NULL};
1348 struct ldb_message_element *el;
1351 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1355 r->out.privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
1356 r->out.privs->count = 0;
1357 r->out.privs->unknown = 0;
1358 r->out.privs->set = NULL;
1360 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
1361 if (sidstr == NULL) {
1362 return NT_STATUS_NO_MEMORY;
1365 ret = gendb_search(astate->policy->sam_ldb, mem_ctx, NULL, &res, attrs,
1366 "objectSid=%s", sidstr);
1368 return NT_STATUS_OK;
1371 el = ldb_msg_find_element(res[0], "privilege");
1372 if (el == NULL || el->num_values == 0) {
1373 return NT_STATUS_OK;
1376 r->out.privs->set = talloc_array(r->out.privs,
1377 struct lsa_LUIDAttribute, el->num_values);
1378 if (r->out.privs->set == NULL) {
1379 return NT_STATUS_NO_MEMORY;
1382 for (i=0;i<el->num_values;i++) {
1383 int id = sec_privilege_id((const char *)el->values[i].data);
1385 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1387 r->out.privs->set[i].attribute = 0;
1388 r->out.privs->set[i].luid.low = id;
1389 r->out.privs->set[i].luid.high = 0;
1392 r->out.privs->count = el->num_values;
1394 return NT_STATUS_OK;
1398 lsa_EnumAccountRights
1400 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
1401 TALLOC_CTX *mem_ctx,
1402 struct lsa_EnumAccountRights *r)
1404 struct dcesrv_handle *h;
1405 struct lsa_policy_state *state;
1407 struct ldb_message **res;
1408 const char * const attrs[] = { "privilege", NULL};
1410 struct ldb_message_element *el;
1412 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1416 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
1417 if (sidstr == NULL) {
1418 return NT_STATUS_NO_MEMORY;
1421 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
1422 "(&(objectSid=%s)(privilege=*))", sidstr);
1424 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1427 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1430 DEBUG(3, ("searching for account rights for SID: %s failed: %s",
1431 dom_sid_string(mem_ctx, r->in.sid),
1432 ldb_errstring(state->sam_ldb)));
1433 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1436 el = ldb_msg_find_element(res[0], "privilege");
1437 if (el == NULL || el->num_values == 0) {
1438 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1441 r->out.rights->count = el->num_values;
1442 r->out.rights->names = talloc_array(r->out.rights,
1443 struct lsa_StringLarge, r->out.rights->count);
1444 if (r->out.rights->names == NULL) {
1445 return NT_STATUS_NO_MEMORY;
1448 for (i=0;i<el->num_values;i++) {
1449 r->out.rights->names[i].string = (const char *)el->values[i].data;
1452 return NT_STATUS_OK;
1458 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
1460 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
1461 TALLOC_CTX *mem_ctx,
1462 struct lsa_policy_state *state,
1464 struct dom_sid *sid,
1465 const struct lsa_RightSet *rights)
1468 struct ldb_message *msg;
1469 struct ldb_message_element *el;
1471 struct lsa_EnumAccountRights r2;
1473 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, sid);
1474 if (sidstr == NULL) {
1475 return NT_STATUS_NO_MEMORY;
1478 msg = ldb_msg_new(mem_ctx);
1480 return NT_STATUS_NO_MEMORY;
1483 msg->dn = samdb_search_dn(state->sam_ldb, mem_ctx,
1484 NULL, "objectSid=%s", sidstr);
1485 if (msg->dn == NULL) {
1487 if (ldb_flag == LDB_FLAG_MOD_DELETE) {
1488 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1490 status = samdb_create_foreign_security_principal(state->sam_ldb, mem_ctx,
1492 if (!NT_STATUS_IS_OK(status)) {
1495 return NT_STATUS_NO_SUCH_USER;
1498 if (ldb_msg_add_empty(msg, "privilege", ldb_flag, NULL)) {
1499 return NT_STATUS_NO_MEMORY;
1502 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1505 r2.in.handle = &state->handle->wire_handle;
1507 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
1509 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1510 if (!NT_STATUS_IS_OK(status)) {
1511 ZERO_STRUCTP(r2.out.rights);
1515 for (i=0;i<rights->count;i++) {
1516 if (sec_privilege_id(rights->names[i].string) == -1) {
1517 return NT_STATUS_NO_SUCH_PRIVILEGE;
1520 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1522 for (j=0;j<r2.out.rights->count;j++) {
1523 if (strcasecmp_m(r2.out.rights->names[j].string,
1524 rights->names[i].string) == 0) {
1528 if (j != r2.out.rights->count) continue;
1531 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
1532 if (ret != LDB_SUCCESS) {
1533 return NT_STATUS_NO_MEMORY;
1537 el = ldb_msg_find_element(msg, "privilege");
1539 return NT_STATUS_OK;
1542 ret = ldb_modify(state->sam_ldb, msg);
1544 if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1545 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1547 DEBUG(3, ("Could not %s attributes from %s: %s",
1548 ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add",
1549 ldb_dn_get_linearized(msg->dn), ldb_errstring(state->sam_ldb)));
1550 return NT_STATUS_UNEXPECTED_IO_ERROR;
1553 return NT_STATUS_OK;
1557 lsa_AddPrivilegesToAccount
1559 static NTSTATUS dcesrv_lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1560 struct lsa_AddPrivilegesToAccount *r)
1562 struct lsa_RightSet rights;
1563 struct dcesrv_handle *h;
1564 struct lsa_account_state *astate;
1567 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1571 rights.count = r->in.privs->count;
1572 rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
1573 if (rights.names == NULL) {
1574 return NT_STATUS_NO_MEMORY;
1576 for (i=0;i<rights.count;i++) {
1577 int id = r->in.privs->set[i].luid.low;
1578 if (r->in.privs->set[i].luid.high) {
1579 return NT_STATUS_NO_SUCH_PRIVILEGE;
1581 rights.names[i].string = sec_privilege_name(id);
1582 if (rights.names[i].string == NULL) {
1583 return NT_STATUS_NO_SUCH_PRIVILEGE;
1587 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1588 LDB_FLAG_MOD_ADD, astate->account_sid,
1594 lsa_RemovePrivilegesFromAccount
1596 static NTSTATUS dcesrv_lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1597 struct lsa_RemovePrivilegesFromAccount *r)
1599 struct lsa_RightSet *rights;
1600 struct dcesrv_handle *h;
1601 struct lsa_account_state *astate;
1604 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1608 rights = talloc(mem_ctx, struct lsa_RightSet);
1610 if (r->in.remove_all == 1 &&
1611 r->in.privs == NULL) {
1612 struct lsa_EnumAccountRights r2;
1615 r2.in.handle = &astate->policy->handle->wire_handle;
1616 r2.in.sid = astate->account_sid;
1617 r2.out.rights = rights;
1619 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1620 if (!NT_STATUS_IS_OK(status)) {
1624 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1625 LDB_FLAG_MOD_DELETE, astate->account_sid,
1629 if (r->in.remove_all != 0) {
1630 return NT_STATUS_INVALID_PARAMETER;
1633 rights->count = r->in.privs->count;
1634 rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
1635 if (rights->names == NULL) {
1636 return NT_STATUS_NO_MEMORY;
1638 for (i=0;i<rights->count;i++) {
1639 int id = r->in.privs->set[i].luid.low;
1640 if (r->in.privs->set[i].luid.high) {
1641 return NT_STATUS_NO_SUCH_PRIVILEGE;
1643 rights->names[i].string = sec_privilege_name(id);
1644 if (rights->names[i].string == NULL) {
1645 return NT_STATUS_NO_SUCH_PRIVILEGE;
1649 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1650 LDB_FLAG_MOD_DELETE, astate->account_sid,
1656 lsa_GetQuotasForAccount
1658 static NTSTATUS dcesrv_lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1659 struct lsa_GetQuotasForAccount *r)
1661 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1666 lsa_SetQuotasForAccount
1668 static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1669 struct lsa_SetQuotasForAccount *r)
1671 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1676 lsa_GetSystemAccessAccount
1678 static NTSTATUS dcesrv_lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1679 struct lsa_GetSystemAccessAccount *r)
1681 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1686 lsa_SetSystemAccessAccount
1688 static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1689 struct lsa_SetSystemAccessAccount *r)
1691 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1698 static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1699 struct lsa_CreateSecret *r)
1701 struct dcesrv_handle *policy_handle;
1702 struct lsa_policy_state *policy_state;
1703 struct lsa_secret_state *secret_state;
1704 struct dcesrv_handle *handle;
1705 struct ldb_message **msgs, *msg;
1707 const char *attrs[] = {
1715 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1716 ZERO_STRUCTP(r->out.sec_handle);
1718 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
1720 case SECURITY_SYSTEM:
1721 case SECURITY_ADMINISTRATOR:
1724 /* Users and annonymous are not allowed create secrets */
1725 return NT_STATUS_ACCESS_DENIED;
1728 policy_state = policy_handle->data;
1730 if (!r->in.name.string) {
1731 return NT_STATUS_INVALID_PARAMETER;
1734 secret_state = talloc(mem_ctx, struct lsa_secret_state);
1735 if (!secret_state) {
1736 return NT_STATUS_NO_MEMORY;
1738 secret_state->policy = policy_state;
1740 msg = ldb_msg_new(mem_ctx);
1742 return NT_STATUS_NO_MEMORY;
1745 if (strncmp("G$", r->in.name.string, 2) == 0) {
1747 name = &r->in.name.string[2];
1748 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
1749 secret_state->global = true;
1751 if (strlen(name) < 1) {
1752 return NT_STATUS_INVALID_PARAMETER;
1755 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
1756 /* search for the secret record */
1757 ret = gendb_search(secret_state->sam_ldb,
1758 mem_ctx, policy_state->system_dn, &msgs, attrs,
1759 "(&(cn=%s)(objectclass=secret))",
1762 return NT_STATUS_OBJECT_NAME_COLLISION;
1766 DEBUG(0,("Failure searching for CN=%s: %s\n",
1767 name2, ldb_errstring(secret_state->sam_ldb)));
1768 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1771 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
1772 if (!name2 || ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
1773 return NT_STATUS_NO_MEMORY;
1776 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
1779 secret_state->global = false;
1781 name = r->in.name.string;
1782 if (strlen(name) < 1) {
1783 return NT_STATUS_INVALID_PARAMETER;
1786 secret_state->sam_ldb = talloc_reference(secret_state,
1787 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
1788 /* search for the secret record */
1789 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
1790 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
1792 "(&(cn=%s)(objectclass=secret))",
1793 ldb_binary_encode_string(mem_ctx, name));
1795 return NT_STATUS_OBJECT_NAME_COLLISION;
1799 DEBUG(0,("Failure searching for CN=%s: %s\n",
1800 name, ldb_errstring(secret_state->sam_ldb)));
1801 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1804 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name);
1805 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
1808 /* pull in all the template attributes. Note this is always from the global samdb */
1809 ret = samdb_copy_template(secret_state->policy->sam_ldb, msg,
1812 DEBUG(0,("Failed to load TemplateSecret from samdb: %s\n",
1814 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1817 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
1819 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
1821 /* create the secret */
1822 ret = ldb_add(secret_state->sam_ldb, msg);
1824 DEBUG(0,("Failed to create secret record %s: %s\n",
1825 ldb_dn_get_linearized(msg->dn),
1826 ldb_errstring(secret_state->sam_ldb)));
1827 return NT_STATUS_ACCESS_DENIED;
1830 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
1832 return NT_STATUS_NO_MEMORY;
1835 handle->data = talloc_steal(handle, secret_state);
1837 secret_state->access_mask = r->in.access_mask;
1838 secret_state->policy = talloc_reference(secret_state, policy_state);
1840 *r->out.sec_handle = handle->wire_handle;
1842 return NT_STATUS_OK;
1849 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1850 struct lsa_OpenSecret *r)
1852 struct dcesrv_handle *policy_handle;
1854 struct lsa_policy_state *policy_state;
1855 struct lsa_secret_state *secret_state;
1856 struct dcesrv_handle *handle;
1857 struct ldb_message **msgs;
1858 const char *attrs[] = {
1866 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1867 ZERO_STRUCTP(r->out.sec_handle);
1868 policy_state = policy_handle->data;
1870 if (!r->in.name.string) {
1871 return NT_STATUS_INVALID_PARAMETER;
1874 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
1876 case SECURITY_SYSTEM:
1877 case SECURITY_ADMINISTRATOR:
1880 /* Users and annonymous are not allowed to access secrets */
1881 return NT_STATUS_ACCESS_DENIED;
1884 secret_state = talloc(mem_ctx, struct lsa_secret_state);
1885 if (!secret_state) {
1886 return NT_STATUS_NO_MEMORY;
1888 secret_state->policy = policy_state;
1890 if (strncmp("G$", r->in.name.string, 2) == 0) {
1891 name = &r->in.name.string[2];
1892 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
1893 secret_state->global = true;
1895 if (strlen(name) < 1) {
1896 return NT_STATUS_INVALID_PARAMETER;
1899 /* search for the secret record */
1900 ret = gendb_search(secret_state->sam_ldb,
1901 mem_ctx, policy_state->system_dn, &msgs, attrs,
1902 "(&(cn=%s Secret)(objectclass=secret))",
1903 ldb_binary_encode_string(mem_ctx, name));
1905 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1909 DEBUG(0,("Found %d records matching DN %s\n", ret,
1910 ldb_dn_get_linearized(policy_state->system_dn)));
1911 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1915 secret_state->global = false;
1916 secret_state->sam_ldb = talloc_reference(secret_state,
1917 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
1919 name = r->in.name.string;
1920 if (strlen(name) < 1) {
1921 return NT_STATUS_INVALID_PARAMETER;
1924 /* search for the secret record */
1925 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
1926 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
1928 "(&(cn=%s)(objectclass=secret))",
1929 ldb_binary_encode_string(mem_ctx, name));
1931 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1935 DEBUG(0,("Found %d records matching CN=%s\n",
1936 ret, ldb_binary_encode_string(mem_ctx, name)));
1937 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1941 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
1943 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
1945 return NT_STATUS_NO_MEMORY;
1948 handle->data = talloc_steal(handle, secret_state);
1950 secret_state->access_mask = r->in.access_mask;
1951 secret_state->policy = talloc_reference(secret_state, policy_state);
1953 *r->out.sec_handle = handle->wire_handle;
1955 return NT_STATUS_OK;
1962 static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1963 struct lsa_SetSecret *r)
1966 struct dcesrv_handle *h;
1967 struct lsa_secret_state *secret_state;
1968 struct ldb_message *msg;
1969 DATA_BLOB session_key;
1970 DATA_BLOB crypt_secret, secret;
1973 NTSTATUS status = NT_STATUS_OK;
1975 struct timeval now = timeval_current();
1976 NTTIME nt_now = timeval_to_nttime(&now);
1978 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
1980 secret_state = h->data;
1982 msg = ldb_msg_new(mem_ctx);
1984 return NT_STATUS_NO_MEMORY;
1987 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
1989 return NT_STATUS_NO_MEMORY;
1991 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
1992 if (!NT_STATUS_IS_OK(status)) {
1996 if (r->in.old_val) {
1998 crypt_secret.data = r->in.old_val->data;
1999 crypt_secret.length = r->in.old_val->size;
2001 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2002 if (!NT_STATUS_IS_OK(status)) {
2006 val.data = secret.data;
2007 val.length = secret.length;
2010 if (samdb_msg_add_value(secret_state->sam_ldb,
2011 mem_ctx, msg, "priorValue", &val) != 0) {
2012 return NT_STATUS_NO_MEMORY;
2015 /* set old value mtime */
2016 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2017 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
2018 return NT_STATUS_NO_MEMORY;
2021 if (!r->in.new_val) {
2022 /* set old value mtime */
2023 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2024 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2025 return NT_STATUS_NO_MEMORY;
2027 if (samdb_msg_add_delete(secret_state->sam_ldb,
2028 mem_ctx, msg, "currentValue")) {
2029 return NT_STATUS_NO_MEMORY;
2034 if (r->in.new_val) {
2036 crypt_secret.data = r->in.new_val->data;
2037 crypt_secret.length = r->in.new_val->size;
2039 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2040 if (!NT_STATUS_IS_OK(status)) {
2044 val.data = secret.data;
2045 val.length = secret.length;
2048 if (samdb_msg_add_value(secret_state->sam_ldb,
2049 mem_ctx, msg, "currentValue", &val) != 0) {
2050 return NT_STATUS_NO_MEMORY;
2053 /* set new value mtime */
2054 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2055 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2056 return NT_STATUS_NO_MEMORY;
2059 /* If the old value is not set, then migrate the
2060 * current value to the old value */
2061 if (!r->in.old_val) {
2062 const struct ldb_val *new_val;
2063 NTTIME last_set_time;
2064 struct ldb_message **res;
2065 const char *attrs[] = {
2071 /* search for the secret record */
2072 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
2073 secret_state->secret_dn, &res, attrs);
2075 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2079 DEBUG(0,("Found %d records matching dn=%s\n", ret,
2080 ldb_dn_get_linearized(secret_state->secret_dn)));
2081 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2084 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2085 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2089 if (samdb_msg_add_value(secret_state->sam_ldb,
2090 mem_ctx, msg, "priorValue",
2092 return NT_STATUS_NO_MEMORY;
2096 /* set new value mtime */
2097 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2098 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2099 mem_ctx, msg, "priorSetTime", last_set_time) != 0) {
2100 return NT_STATUS_NO_MEMORY;
2106 /* modify the samdb record */
2107 ret = samdb_replace(secret_state->sam_ldb, mem_ctx, msg);
2109 /* we really need samdb.c to return NTSTATUS */
2110 return NT_STATUS_UNSUCCESSFUL;
2113 return NT_STATUS_OK;
2120 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2121 struct lsa_QuerySecret *r)
2123 struct dcesrv_handle *h;
2124 struct lsa_secret_state *secret_state;
2125 struct ldb_message *msg;
2126 DATA_BLOB session_key;
2127 DATA_BLOB crypt_secret, secret;
2129 struct ldb_message **res;
2130 const char *attrs[] = {
2140 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2142 /* Ensure user is permitted to read this... */
2143 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2145 case SECURITY_SYSTEM:
2146 case SECURITY_ADMINISTRATOR:
2149 /* Users and annonymous are not allowed to read secrets */
2150 return NT_STATUS_ACCESS_DENIED;
2153 secret_state = h->data;
2155 /* pull all the user attributes */
2156 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2157 secret_state->secret_dn, &res, attrs);
2159 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2163 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2164 if (!NT_STATUS_IS_OK(nt_status)) {
2168 if (r->in.old_val) {
2169 const struct ldb_val *prior_val;
2170 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2171 if (!r->out.old_val) {
2172 return NT_STATUS_NO_MEMORY;
2174 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
2176 if (prior_val && prior_val->length) {
2177 secret.data = prior_val->data;
2178 secret.length = prior_val->length;
2181 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2182 if (!crypt_secret.length) {
2183 return NT_STATUS_NO_MEMORY;
2185 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2186 if (!r->out.old_val->buf) {
2187 return NT_STATUS_NO_MEMORY;
2189 r->out.old_val->buf->size = crypt_secret.length;
2190 r->out.old_val->buf->length = crypt_secret.length;
2191 r->out.old_val->buf->data = crypt_secret.data;
2195 if (r->in.old_mtime) {
2196 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2197 if (!r->out.old_mtime) {
2198 return NT_STATUS_NO_MEMORY;
2200 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
2203 if (r->in.new_val) {
2204 const struct ldb_val *new_val;
2205 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2206 if (!r->out.new_val) {
2207 return NT_STATUS_NO_MEMORY;
2210 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2212 if (new_val && new_val->length) {
2213 secret.data = new_val->data;
2214 secret.length = new_val->length;
2217 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2218 if (!crypt_secret.length) {
2219 return NT_STATUS_NO_MEMORY;
2221 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2222 if (!r->out.new_val->buf) {
2223 return NT_STATUS_NO_MEMORY;
2225 r->out.new_val->buf->length = crypt_secret.length;
2226 r->out.new_val->buf->size = crypt_secret.length;
2227 r->out.new_val->buf->data = crypt_secret.data;
2231 if (r->in.new_mtime) {
2232 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2233 if (!r->out.new_mtime) {
2234 return NT_STATUS_NO_MEMORY;
2236 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2239 return NT_STATUS_OK;
2246 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
2247 TALLOC_CTX *mem_ctx,
2248 struct lsa_LookupPrivValue *r)
2250 struct dcesrv_handle *h;
2251 struct lsa_policy_state *state;
2254 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2258 id = sec_privilege_id(r->in.name->string);
2260 return NT_STATUS_NO_SUCH_PRIVILEGE;
2263 r->out.luid->low = id;
2264 r->out.luid->high = 0;
2266 return NT_STATUS_OK;
2273 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
2274 TALLOC_CTX *mem_ctx,
2275 struct lsa_LookupPrivName *r)
2277 struct dcesrv_handle *h;
2278 struct lsa_policy_state *state;
2279 const char *privname;
2281 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2285 if (r->in.luid->high != 0) {
2286 return NT_STATUS_NO_SUCH_PRIVILEGE;
2289 privname = sec_privilege_name(r->in.luid->low);
2290 if (privname == NULL) {
2291 return NT_STATUS_NO_SUCH_PRIVILEGE;
2294 r->out.name = talloc(mem_ctx, struct lsa_StringLarge);
2295 if (r->out.name == NULL) {
2296 return NT_STATUS_NO_MEMORY;
2298 r->out.name->string = privname;
2300 return NT_STATUS_OK;
2305 lsa_LookupPrivDisplayName
2307 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
2308 TALLOC_CTX *mem_ctx,
2309 struct lsa_LookupPrivDisplayName *r)
2311 struct dcesrv_handle *h;
2312 struct lsa_policy_state *state;
2315 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2319 id = sec_privilege_id(r->in.name->string);
2321 return NT_STATUS_NO_SUCH_PRIVILEGE;
2324 r->out.disp_name = talloc(mem_ctx, struct lsa_StringLarge);
2325 if (r->out.disp_name == NULL) {
2326 return NT_STATUS_NO_MEMORY;
2329 r->out.disp_name->string = sec_privilege_display_name(id, r->in.language_id);
2330 if (r->out.disp_name->string == NULL) {
2331 return NT_STATUS_INTERNAL_ERROR;
2334 return NT_STATUS_OK;
2339 lsa_EnumAccountsWithUserRight
2341 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
2342 TALLOC_CTX *mem_ctx,
2343 struct lsa_EnumAccountsWithUserRight *r)
2345 struct dcesrv_handle *h;
2346 struct lsa_policy_state *state;
2348 struct ldb_message **res;
2349 const char * const attrs[] = { "objectSid", NULL};
2350 const char *privname;
2352 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2356 if (r->in.name == NULL) {
2357 return NT_STATUS_NO_SUCH_PRIVILEGE;
2360 privname = r->in.name->string;
2361 if (sec_privilege_id(privname) == -1) {
2362 return NT_STATUS_NO_SUCH_PRIVILEGE;
2365 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
2366 "privilege=%s", privname);
2368 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2371 return NT_STATUS_NO_MORE_ENTRIES;
2374 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2375 if (r->out.sids->sids == NULL) {
2376 return NT_STATUS_NO_MEMORY;
2378 for (i=0;i<ret;i++) {
2379 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2380 res[i], "objectSid");
2381 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2383 r->out.sids->num_sids = ret;
2385 return NT_STATUS_OK;
2390 lsa_AddAccountRights
2392 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
2393 TALLOC_CTX *mem_ctx,
2394 struct lsa_AddAccountRights *r)
2396 struct dcesrv_handle *h;
2397 struct lsa_policy_state *state;
2399 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2403 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2405 r->in.sid, r->in.rights);
2410 lsa_RemoveAccountRights
2412 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
2413 TALLOC_CTX *mem_ctx,
2414 struct lsa_RemoveAccountRights *r)
2416 struct dcesrv_handle *h;
2417 struct lsa_policy_state *state;
2419 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2423 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2424 LDB_FLAG_MOD_DELETE,
2425 r->in.sid, r->in.rights);
2430 lsa_StorePrivateData
2432 static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2433 struct lsa_StorePrivateData *r)
2435 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2440 lsa_RetrievePrivateData
2442 static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2443 struct lsa_RetrievePrivateData *r)
2445 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2452 static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2453 struct lsa_GetUserName *r)
2455 NTSTATUS status = NT_STATUS_OK;
2456 const char *account_name;
2457 const char *authority_name;
2458 struct lsa_String *_account_name;
2459 struct lsa_StringPointer *_authority_name = NULL;
2461 /* this is what w2k3 does */
2462 r->out.account_name = r->in.account_name;
2463 r->out.authority_name = r->in.authority_name;
2465 if (r->in.account_name && r->in.account_name->string) {
2466 return NT_STATUS_INVALID_PARAMETER;
2469 if (r->in.authority_name &&
2470 r->in.authority_name->string &&
2471 r->in.authority_name->string->string) {
2472 return NT_STATUS_INVALID_PARAMETER;
2475 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
2476 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
2478 _account_name = talloc(mem_ctx, struct lsa_String);
2479 NT_STATUS_HAVE_NO_MEMORY(_account_name);
2480 _account_name->string = account_name;
2482 if (r->in.authority_name) {
2483 _authority_name = talloc(mem_ctx, struct lsa_StringPointer);
2484 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
2485 _authority_name->string = talloc(mem_ctx, struct lsa_String);
2486 NT_STATUS_HAVE_NO_MEMORY(_authority_name->string);
2487 _authority_name->string->string = authority_name;
2490 r->out.account_name = _account_name;
2491 r->out.authority_name = _authority_name;
2499 static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
2500 TALLOC_CTX *mem_ctx,
2501 struct lsa_SetInfoPolicy2 *r)
2503 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2507 lsa_QueryDomainInformationPolicy
2509 static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2510 TALLOC_CTX *mem_ctx,
2511 struct lsa_QueryDomainInformationPolicy *r)
2513 r->out.info = talloc(mem_ctx, union lsa_DomainInformationPolicy);
2515 return NT_STATUS_NO_MEMORY;
2518 switch (r->in.level) {
2519 case LSA_DOMAIN_INFO_POLICY_EFS:
2520 talloc_free(r->out.info);
2522 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2523 case LSA_DOMAIN_INFO_POLICY_KERBEROS:
2525 struct lsa_DomainInfoKerberos *k = &r->out.info->kerberos_info;
2526 struct smb_krb5_context *smb_krb5_context;
2527 int ret = smb_krb5_init_context(mem_ctx,
2528 dce_call->event_ctx,
2529 dce_call->conn->dce_ctx->lp_ctx,
2532 talloc_free(r->out.info);
2534 return NT_STATUS_INTERNAL_ERROR;
2536 k->enforce_restrictions = 0; /* FIXME, details missing from MS-LSAD 2.2.53 */
2537 k->service_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
2538 k->user_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
2539 k->user_tkt_renewaltime = 0; /* Need to find somewhere to store this, and query in KDC too */
2540 k->clock_skew = krb5_get_max_time_skew(smb_krb5_context->krb5_context);
2541 talloc_free(smb_krb5_context);
2542 return NT_STATUS_OK;
2545 talloc_free(r->out.info);
2547 return NT_STATUS_INVALID_INFO_CLASS;
2552 lsa_SetDomInfoPolicy
2554 static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2555 TALLOC_CTX *mem_ctx,
2556 struct lsa_SetDomainInformationPolicy *r)
2558 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2564 static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
2565 TALLOC_CTX *mem_ctx,
2566 struct lsa_TestCall *r)
2568 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2574 static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2575 struct lsa_CREDRWRITE *r)
2577 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2584 static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2585 struct lsa_CREDRREAD *r)
2587 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2594 static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2595 struct lsa_CREDRENUMERATE *r)
2597 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2602 lsa_CREDRWRITEDOMAINCREDENTIALS
2604 static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2605 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
2607 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2612 lsa_CREDRREADDOMAINCREDENTIALS
2614 static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2615 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
2617 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2624 static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2625 struct lsa_CREDRDELETE *r)
2627 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2632 lsa_CREDRGETTARGETINFO
2634 static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2635 struct lsa_CREDRGETTARGETINFO *r)
2637 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2642 lsa_CREDRPROFILELOADED
2644 static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2645 struct lsa_CREDRPROFILELOADED *r)
2647 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2652 lsa_CREDRGETSESSIONTYPES
2654 static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2655 struct lsa_CREDRGETSESSIONTYPES *r)
2657 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2662 lsa_LSARREGISTERAUDITEVENT
2664 static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2665 struct lsa_LSARREGISTERAUDITEVENT *r)
2667 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2672 lsa_LSARGENAUDITEVENT
2674 static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2675 struct lsa_LSARGENAUDITEVENT *r)
2677 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2682 lsa_LSARUNREGISTERAUDITEVENT
2684 static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2685 struct lsa_LSARUNREGISTERAUDITEVENT *r)
2687 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2692 lsa_lsaRQueryForestTrustInformation
2694 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2695 struct lsa_lsaRQueryForestTrustInformation *r)
2697 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2702 lsa_LSARSETFORESTTRUSTINFORMATION
2704 static NTSTATUS dcesrv_lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2705 struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
2707 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2714 static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2715 struct lsa_CREDRRENAME *r)
2717 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2723 lsa_LSAROPENPOLICYSCE
2725 static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2726 struct lsa_LSAROPENPOLICYSCE *r)
2728 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2733 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
2735 static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2736 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
2738 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2743 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
2745 static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2746 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
2748 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2753 lsa_LSARADTREPORTSECURITYEVENT
2755 static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2756 struct lsa_LSARADTREPORTSECURITYEVENT *r)
2758 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2762 /* include the generated boilerplate */
2763 #include "librpc/gen_ndr/ndr_lsa_s.c"
2767 /*****************************************
2768 NOTE! The remaining calls below were
2769 removed in w2k3, so the DCESRV_FAULT()
2770 replies are the correct implementation. Do
2771 not try and fill these in with anything else
2772 ******************************************/
2775 dssetup_DsRoleDnsNameToFlatName
2777 static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2778 struct dssetup_DsRoleDnsNameToFlatName *r)
2780 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2785 dssetup_DsRoleDcAsDc
2787 static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2788 struct dssetup_DsRoleDcAsDc *r)
2790 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2795 dssetup_DsRoleDcAsReplica
2797 static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2798 struct dssetup_DsRoleDcAsReplica *r)
2800 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2805 dssetup_DsRoleDemoteDc
2807 static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2808 struct dssetup_DsRoleDemoteDc *r)
2810 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2815 dssetup_DsRoleGetDcOperationProgress
2817 static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2818 struct dssetup_DsRoleGetDcOperationProgress *r)
2820 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2825 dssetup_DsRoleGetDcOperationResults
2827 static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2828 struct dssetup_DsRoleGetDcOperationResults *r)
2830 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2835 dssetup_DsRoleCancel
2837 static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2838 struct dssetup_DsRoleCancel *r)
2840 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2845 dssetup_DsRoleServerSaveStateForUpgrade
2847 static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2848 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
2850 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2855 dssetup_DsRoleUpgradeDownlevelServer
2857 static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2858 struct dssetup_DsRoleUpgradeDownlevelServer *r)
2860 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2865 dssetup_DsRoleAbortDownlevelServerUpgrade
2867 static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2868 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
2870 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2874 /* include the generated boilerplate */
2875 #include "librpc/gen_ndr/ndr_dssetup_s.c"
2877 NTSTATUS dcerpc_server_lsa_init(void)
2881 ret = dcerpc_server_dssetup_init();
2882 if (!NT_STATUS_IS_OK(ret)) {
2885 ret = dcerpc_server_lsarpc_init();
2886 if (!NT_STATUS_IS_OK(ret)) {