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-2005
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 2 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, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include "rpc_server/dcerpc_server.h"
26 #include "rpc_server/common/common.h"
27 #include "auth/auth.h"
28 #include "dsdb/samdb/samdb.h"
29 #include "libcli/ldap/ldap.h"
30 #include "lib/ldb/include/ldb_errors.h"
31 #include "libcli/security/security.h"
32 #include "libcli/auth/libcli_auth.h"
33 #include "param/secrets.h"
35 #include "librpc/gen_ndr/ndr_dssetup.h"
38 this type allows us to distinguish handle types
44 LSA_HANDLE_TRUSTED_DOMAIN
48 state associated with a lsa_OpenPolicy() operation
50 struct lsa_policy_state
{
51 struct dcesrv_handle
*handle
;
52 struct ldb_context
*sam_ldb
;
53 struct sidmap_context
*sidmap
;
55 const struct ldb_dn
*domain_dn
;
56 const struct ldb_dn
*builtin_dn
;
57 const struct ldb_dn
*system_dn
;
58 const char *domain_name
;
59 const char *domain_dns
;
60 struct dom_sid
*domain_sid
;
61 struct GUID domain_guid
;
62 struct dom_sid
*builtin_sid
;
68 state associated with a lsa_OpenAccount() operation
70 struct lsa_account_state
{
71 struct lsa_policy_state
*policy
;
73 struct dom_sid
*account_sid
;
78 state associated with a lsa_OpenSecret() operation
80 struct lsa_secret_state
{
81 struct lsa_policy_state
*policy
;
83 struct ldb_dn
*secret_dn
;
84 struct ldb_context
*sam_ldb
;
89 state associated with a lsa_OpenTrustedDomain() operation
91 struct lsa_trusted_domain_state
{
92 struct lsa_policy_state
*policy
;
94 const struct ldb_dn
*trusted_domain_dn
;
97 static NTSTATUS
lsa_EnumAccountRights(struct dcesrv_call_state
*dce_call
,
99 struct lsa_EnumAccountRights
*r
);
101 static NTSTATUS
lsa_AddRemoveAccountRights(struct dcesrv_call_state
*dce_call
,
103 struct lsa_policy_state
*state
,
106 const struct lsa_RightSet
*rights
);
111 static NTSTATUS
lsa_Close(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
114 struct dcesrv_handle
*h
;
116 *r
->out
.handle
= *r
->in
.handle
;
118 DCESRV_PULL_HANDLE(h
, r
->in
.handle
, DCESRV_HANDLE_ANY
);
122 ZERO_STRUCTP(r
->out
.handle
);
131 static NTSTATUS
lsa_Delete(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
132 struct lsa_Delete
*r
)
134 struct dcesrv_handle
*h
;
137 DCESRV_PULL_HANDLE(h
, r
->in
.handle
, DCESRV_HANDLE_ANY
);
138 if (h
->wire_handle
.handle_type
== LSA_HANDLE_SECRET
) {
139 struct lsa_secret_state
*secret_state
= h
->data
;
140 ret
= samdb_delete(secret_state
->sam_ldb
, mem_ctx
, secret_state
->secret_dn
);
143 return NT_STATUS_INVALID_HANDLE
;
147 } else if (h
->wire_handle
.handle_type
== LSA_HANDLE_TRUSTED_DOMAIN
) {
148 struct lsa_trusted_domain_state
*trusted_domain_state
= h
->data
;
149 ret
= samdb_delete(trusted_domain_state
->policy
->sam_ldb
, mem_ctx
,
150 trusted_domain_state
->trusted_domain_dn
);
153 return NT_STATUS_INVALID_HANDLE
;
157 } else if (h
->wire_handle
.handle_type
== LSA_HANDLE_ACCOUNT
) {
158 struct lsa_RightSet
*rights
;
159 struct lsa_account_state
*astate
;
160 struct lsa_EnumAccountRights r2
;
163 rights
= talloc(mem_ctx
, struct lsa_RightSet
);
165 DCESRV_PULL_HANDLE(h
, r
->in
.handle
, LSA_HANDLE_ACCOUNT
);
169 r2
.in
.handle
= &astate
->policy
->handle
->wire_handle
;
170 r2
.in
.sid
= astate
->account_sid
;
171 r2
.out
.rights
= rights
;
173 status
= lsa_EnumAccountRights(dce_call
, mem_ctx
, &r2
);
174 if (NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
178 if (!NT_STATUS_IS_OK(status
)) {
182 status
= lsa_AddRemoveAccountRights(dce_call
, mem_ctx
, astate
->policy
,
183 LDB_FLAG_MOD_DELETE
, astate
->account_sid
,
185 if (NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
189 if (!NT_STATUS_IS_OK(status
)) {
194 return NT_STATUS_INVALID_HANDLE
;
201 static NTSTATUS
lsa_EnumPrivs(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
202 struct lsa_EnumPrivs
*r
)
204 struct dcesrv_handle
*h
;
205 struct lsa_policy_state
*state
;
207 const char *privname
;
209 DCESRV_PULL_HANDLE(h
, r
->in
.handle
, LSA_HANDLE_POLICY
);
213 i
= *r
->in
.resume_handle
;
216 while ((privname
= sec_privilege_name(i
)) &&
217 r
->out
.privs
->count
< r
->in
.max_count
) {
218 struct lsa_PrivEntry
*e
;
220 r
->out
.privs
->privs
= talloc_realloc(r
->out
.privs
,
222 struct lsa_PrivEntry
,
223 r
->out
.privs
->count
+1);
224 if (r
->out
.privs
->privs
== NULL
) {
225 return NT_STATUS_NO_MEMORY
;
227 e
= &r
->out
.privs
->privs
[r
->out
.privs
->count
];
230 e
->name
.string
= privname
;
231 r
->out
.privs
->count
++;
235 *r
->out
.resume_handle
= i
;
244 static NTSTATUS
lsa_QuerySecurity(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
245 struct lsa_QuerySecurity
*r
)
247 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
254 static NTSTATUS
lsa_SetSecObj(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
255 struct lsa_SetSecObj
*r
)
257 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
264 static NTSTATUS
lsa_ChangePassword(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
265 struct lsa_ChangePassword
*r
)
267 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
270 static NTSTATUS
lsa_get_policy_state(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
271 struct lsa_policy_state
**_state
)
273 struct lsa_policy_state
*state
;
274 const struct ldb_dn
*partitions_basedn
;
275 struct ldb_result
*dom_res
;
276 const char *dom_attrs
[] = {
282 struct ldb_result
*ref_res
;
283 const char *ref_attrs
[] = {
291 state
= talloc(mem_ctx
, struct lsa_policy_state
);
293 return NT_STATUS_NO_MEMORY
;
296 /* make sure the sam database is accessible */
297 state
->sam_ldb
= samdb_connect(state
, dce_call
->conn
->auth_state
.session_info
);
298 if (state
->sam_ldb
== NULL
) {
299 return NT_STATUS_INVALID_SYSTEM_SERVICE
;
302 partitions_basedn
= samdb_partitions_dn(state
->sam_ldb
, mem_ctx
);
304 state
->sidmap
= sidmap_open(state
);
305 if (state
->sidmap
== NULL
) {
306 return NT_STATUS_INVALID_SYSTEM_SERVICE
;
309 /* work out the domain_dn - useful for so many calls its worth
311 state
->domain_dn
= samdb_base_dn(state
->sam_ldb
);
312 if (!state
->domain_dn
) {
313 return NT_STATUS_NO_MEMORY
;
316 ret
= ldb_search(state
->sam_ldb
, state
->domain_dn
, LDB_SCOPE_BASE
, NULL
, dom_attrs
, &dom_res
);
318 if (ret
!= LDB_SUCCESS
) {
319 return NT_STATUS_INVALID_SYSTEM_SERVICE
;
321 talloc_steal(state
, dom_res
);
322 if (dom_res
->count
!= 1) {
323 return NT_STATUS_NO_SUCH_DOMAIN
;
326 state
->domain_sid
= samdb_result_dom_sid(state
, dom_res
->msgs
[0], "objectSid");
327 if (!state
->domain_sid
) {
328 return NT_STATUS_NO_SUCH_DOMAIN
;
331 state
->domain_guid
= samdb_result_guid(dom_res
->msgs
[0], "objectGUID");
332 if (!state
->domain_sid
) {
333 return NT_STATUS_NO_SUCH_DOMAIN
;
336 state
->mixed_domain
= ldb_msg_find_attr_as_uint(dom_res
->msgs
[0], "nTMixedDomain", 0);
338 talloc_free(dom_res
);
340 ref_filter
= talloc_asprintf(state
, "(&(objectclass=crossRef)(ncName=%s))",
341 ldb_dn_linearize(mem_ctx
, state
->domain_dn
));
343 return NT_STATUS_NO_MEMORY
;
346 ret
= ldb_search(state
->sam_ldb
, partitions_basedn
, LDB_SCOPE_SUBTREE
, ref_filter
, ref_attrs
, &ref_res
);
347 talloc_steal(state
, ref_res
);
348 talloc_free(ref_filter
);
350 if (ret
!= LDB_SUCCESS
) {
351 return NT_STATUS_INVALID_SYSTEM_SERVICE
;
353 if (ref_res
->count
!= 1) {
354 return NT_STATUS_NO_SUCH_DOMAIN
;
357 state
->domain_name
= ldb_msg_find_attr_as_string(ref_res
->msgs
[0], "nETBIOSName", NULL
);
358 if (!state
->domain_name
) {
359 return NT_STATUS_NO_SUCH_DOMAIN
;
361 talloc_steal(state
, state
->domain_name
);
363 state
->domain_dns
= ldb_msg_find_attr_as_string(ref_res
->msgs
[0], "dnsRoot", NULL
);
364 if (!state
->domain_dns
) {
365 return NT_STATUS_NO_SUCH_DOMAIN
;
367 talloc_steal(state
, state
->domain_dns
);
369 talloc_free(ref_res
);
371 /* work out the builtin_dn - useful for so many calls its worth
373 state
->builtin_dn
= samdb_search_dn(state
->sam_ldb
, state
, state
->domain_dn
, "(objectClass=builtinDomain)");
374 if (!state
->builtin_dn
) {
375 return NT_STATUS_NO_SUCH_DOMAIN
;
378 /* work out the system_dn - useful for so many calls its worth
380 state
->system_dn
= samdb_search_dn(state
->sam_ldb
, state
,
381 state
->domain_dn
, "(&(objectClass=container)(cn=System))");
382 if (!state
->system_dn
) {
383 return NT_STATUS_NO_SUCH_DOMAIN
;
386 state
->builtin_sid
= dom_sid_parse_talloc(state
, SID_BUILTIN
);
387 if (!state
->builtin_sid
) {
388 return NT_STATUS_NO_SUCH_DOMAIN
;
397 dssetup_DsRoleGetPrimaryDomainInformation
399 This is not an LSA call, but is the only call left on the DSSETUP
400 pipe (after the pipe was truncated), and needs lsa_get_policy_state
402 static WERROR
dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state
*dce_call
,
404 struct dssetup_DsRoleGetPrimaryDomainInformation
*r
)
406 union dssetup_DsRoleInfo
*info
;
408 info
= talloc(mem_ctx
, union dssetup_DsRoleInfo
);
409 W_ERROR_HAVE_NO_MEMORY(info
);
411 switch (r
->in
.level
) {
412 case DS_ROLE_BASIC_INFORMATION
:
414 enum dssetup_DsRole role
= DS_ROLE_STANDALONE_SERVER
;
416 const char *domain
= NULL
;
417 const char *dns_domain
= NULL
;
418 const char *forest
= NULL
;
419 struct GUID domain_guid
;
420 struct lsa_policy_state
*state
;
422 NTSTATUS status
= lsa_get_policy_state(dce_call
, mem_ctx
, &state
);
423 if (!NT_STATUS_IS_OK(status
)) {
424 return ntstatus_to_werror(status
);
427 ZERO_STRUCT(domain_guid
);
429 switch (lp_server_role()) {
430 case ROLE_STANDALONE
:
431 role
= DS_ROLE_STANDALONE_SERVER
;
433 case ROLE_DOMAIN_MEMBER
:
434 role
= DS_ROLE_MEMBER_SERVER
;
436 case ROLE_DOMAIN_BDC
:
437 role
= DS_ROLE_BACKUP_DC
;
439 case ROLE_DOMAIN_PDC
:
440 role
= DS_ROLE_PRIMARY_DC
;
444 switch (lp_server_role()) {
445 case ROLE_STANDALONE
:
446 domain
= talloc_strdup(mem_ctx
, lp_workgroup());
447 W_ERROR_HAVE_NO_MEMORY(domain
);
449 case ROLE_DOMAIN_MEMBER
:
450 domain
= talloc_strdup(mem_ctx
, lp_workgroup());
451 W_ERROR_HAVE_NO_MEMORY(domain
);
452 /* TODO: what is with dns_domain and forest and guid? */
454 case ROLE_DOMAIN_BDC
:
455 case ROLE_DOMAIN_PDC
:
456 flags
= DS_ROLE_PRIMARY_DS_RUNNING
;
458 if (state
->mixed_domain
== 1) {
459 flags
|= DS_ROLE_PRIMARY_DS_MIXED_MODE
;
462 domain
= state
->domain_name
;
463 dns_domain
= state
->domain_dns
;
464 forest
= state
->domain_dns
;
466 domain_guid
= state
->domain_guid
;
467 flags
|= DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT
;
471 info
->basic
.role
= role
;
472 info
->basic
.flags
= flags
;
473 info
->basic
.domain
= domain
;
474 info
->basic
.dns_domain
= dns_domain
;
475 info
->basic
.forest
= forest
;
476 info
->basic
.domain_guid
= domain_guid
;
481 case DS_ROLE_UPGRADE_STATUS
:
483 info
->upgrade
.upgrading
= DS_ROLE_NOT_UPGRADING
;
484 info
->upgrade
.previous_role
= DS_ROLE_PREVIOUS_UNKNOWN
;
489 case DS_ROLE_OP_STATUS
:
491 info
->opstatus
.status
= DS_ROLE_OP_IDLE
;
497 return WERR_INVALID_PARAM
;
500 return WERR_INVALID_PARAM
;
506 static NTSTATUS
lsa_OpenPolicy2(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
507 struct lsa_OpenPolicy2
*r
)
510 struct lsa_policy_state
*state
;
511 struct dcesrv_handle
*handle
;
513 ZERO_STRUCTP(r
->out
.handle
);
515 status
= lsa_get_policy_state(dce_call
, mem_ctx
, &state
);
516 if (!NT_STATUS_IS_OK(status
)) {
520 handle
= dcesrv_handle_new(dce_call
->context
, LSA_HANDLE_POLICY
);
522 return NT_STATUS_NO_MEMORY
;
525 handle
->data
= talloc_steal(handle
, state
);
527 state
->access_mask
= r
->in
.access_mask
;
528 state
->handle
= handle
;
529 *r
->out
.handle
= handle
->wire_handle
;
531 /* note that we have completely ignored the attr element of
532 the OpenPolicy. As far as I can tell, this is what w2k3
540 a wrapper around lsa_OpenPolicy2
542 static NTSTATUS
lsa_OpenPolicy(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
543 struct lsa_OpenPolicy
*r
)
545 struct lsa_OpenPolicy2 r2
;
547 r2
.in
.system_name
= NULL
;
548 r2
.in
.attr
= r
->in
.attr
;
549 r2
.in
.access_mask
= r
->in
.access_mask
;
550 r2
.out
.handle
= r
->out
.handle
;
552 return lsa_OpenPolicy2(dce_call
, mem_ctx
, &r2
);
559 fill in the AccountDomain info
561 static NTSTATUS
lsa_info_AccountDomain(struct lsa_policy_state
*state
, TALLOC_CTX
*mem_ctx
,
562 struct lsa_DomainInfo
*info
)
564 info
->name
.string
= state
->domain_name
;
565 info
->sid
= state
->domain_sid
;
571 fill in the DNS domain info
573 static NTSTATUS
lsa_info_DNS(struct lsa_policy_state
*state
, TALLOC_CTX
*mem_ctx
,
574 struct lsa_DnsDomainInfo
*info
)
576 info
->name
.string
= state
->domain_name
;
577 info
->sid
= state
->domain_sid
;
578 info
->dns_domain
.string
= state
->domain_dns
;
579 info
->dns_forest
.string
= state
->domain_dns
;
580 info
->domain_guid
= state
->domain_guid
;
588 static NTSTATUS
lsa_QueryInfoPolicy2(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
589 struct lsa_QueryInfoPolicy2
*r
)
591 struct lsa_policy_state
*state
;
592 struct dcesrv_handle
*h
;
596 DCESRV_PULL_HANDLE(h
, r
->in
.handle
, LSA_HANDLE_POLICY
);
600 r
->out
.info
= talloc(mem_ctx
, union lsa_PolicyInformation
);
602 return NT_STATUS_NO_MEMORY
;
605 ZERO_STRUCTP(r
->out
.info
);
607 switch (r
->in
.level
) {
608 case LSA_POLICY_INFO_DOMAIN
:
609 case LSA_POLICY_INFO_ACCOUNT_DOMAIN
:
610 return lsa_info_AccountDomain(state
, mem_ctx
, &r
->out
.info
->account_domain
);
612 case LSA_POLICY_INFO_DNS
:
613 return lsa_info_DNS(state
, mem_ctx
, &r
->out
.info
->dns
);
616 return NT_STATUS_INVALID_INFO_CLASS
;
622 static NTSTATUS
lsa_QueryInfoPolicy(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
623 struct lsa_QueryInfoPolicy
*r
)
625 struct lsa_QueryInfoPolicy2 r2
;
628 r2
.in
.handle
= r
->in
.handle
;
629 r2
.in
.level
= r
->in
.level
;
631 status
= lsa_QueryInfoPolicy2(dce_call
, mem_ctx
, &r2
);
633 r
->out
.info
= r2
.out
.info
;
641 static NTSTATUS
lsa_SetInfoPolicy(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
642 struct lsa_SetInfoPolicy
*r
)
644 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
651 static NTSTATUS
lsa_ClearAuditLog(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
652 struct lsa_ClearAuditLog
*r
)
654 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
661 static NTSTATUS
lsa_CreateAccount(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
662 struct lsa_CreateAccount
*r
)
664 struct lsa_account_state
*astate
;
666 struct lsa_policy_state
*state
;
667 struct dcesrv_handle
*h
, *ah
;
669 ZERO_STRUCTP(r
->out
.acct_handle
);
671 DCESRV_PULL_HANDLE(h
, r
->in
.handle
, LSA_HANDLE_POLICY
);
675 astate
= talloc(dce_call
->conn
, struct lsa_account_state
);
676 if (astate
== NULL
) {
677 return NT_STATUS_NO_MEMORY
;
680 astate
->account_sid
= dom_sid_dup(astate
, r
->in
.sid
);
681 if (astate
->account_sid
== NULL
) {
683 return NT_STATUS_NO_MEMORY
;
686 astate
->policy
= talloc_reference(astate
, state
);
687 astate
->access_mask
= r
->in
.access_mask
;
689 ah
= dcesrv_handle_new(dce_call
->context
, LSA_HANDLE_ACCOUNT
);
692 return NT_STATUS_NO_MEMORY
;
695 ah
->data
= talloc_steal(ah
, astate
);
697 *r
->out
.acct_handle
= ah
->wire_handle
;
706 static NTSTATUS
lsa_EnumAccounts(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
707 struct lsa_EnumAccounts
*r
)
709 struct dcesrv_handle
*h
;
710 struct lsa_policy_state
*state
;
712 struct ldb_message
**res
;
713 const char * const attrs
[] = { "objectSid", NULL
};
716 DCESRV_PULL_HANDLE(h
, r
->in
.handle
, LSA_HANDLE_POLICY
);
720 /* NOTE: This call must only return accounts that have at least
723 ret
= gendb_search(state
->sam_ldb
, mem_ctx
, NULL
, &res
, attrs
,
724 "(&(objectSid=*)(privilege=*))");
726 return NT_STATUS_NO_SUCH_USER
;
729 if (*r
->in
.resume_handle
>= ret
) {
730 return NT_STATUS_NO_MORE_ENTRIES
;
733 count
= ret
- *r
->in
.resume_handle
;
734 if (count
> r
->in
.num_entries
) {
735 count
= r
->in
.num_entries
;
739 return NT_STATUS_NO_MORE_ENTRIES
;
742 r
->out
.sids
->sids
= talloc_array(r
->out
.sids
, struct lsa_SidPtr
, count
);
743 if (r
->out
.sids
->sids
== NULL
) {
744 return NT_STATUS_NO_MEMORY
;
747 for (i
=0;i
<count
;i
++) {
748 r
->out
.sids
->sids
[i
].sid
=
749 samdb_result_dom_sid(r
->out
.sids
->sids
,
750 res
[i
+ *r
->in
.resume_handle
],
752 NT_STATUS_HAVE_NO_MEMORY(r
->out
.sids
->sids
[i
].sid
);
755 r
->out
.sids
->num_sids
= count
;
756 *r
->out
.resume_handle
= count
+ *r
->in
.resume_handle
;
764 lsa_CreateTrustedDomainEx2
766 static NTSTATUS
lsa_CreateTrustedDomainEx2(struct dcesrv_call_state
*dce_call
,
768 struct lsa_CreateTrustedDomainEx2
*r
)
770 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
774 lsa_CreateTrustedDomainEx
776 static NTSTATUS
lsa_CreateTrustedDomainEx(struct dcesrv_call_state
*dce_call
,
778 struct lsa_CreateTrustedDomainEx
*r
)
780 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
784 lsa_CreateTrustedDomain
786 static NTSTATUS
lsa_CreateTrustedDomain(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
787 struct lsa_CreateTrustedDomain
*r
)
789 struct dcesrv_handle
*policy_handle
;
790 struct lsa_policy_state
*policy_state
;
791 struct lsa_trusted_domain_state
*trusted_domain_state
;
792 struct dcesrv_handle
*handle
;
793 struct ldb_message
**msgs
, *msg
;
794 const char *attrs
[] = {
800 DCESRV_PULL_HANDLE(policy_handle
, r
->in
.handle
, LSA_HANDLE_POLICY
);
801 ZERO_STRUCTP(r
->out
.trustdom_handle
);
803 policy_state
= policy_handle
->data
;
805 if (!r
->in
.info
->name
.string
) {
806 return NT_STATUS_INVALID_PARAMETER
;
808 name
= r
->in
.info
->name
.string
;
810 trusted_domain_state
= talloc(mem_ctx
, struct lsa_trusted_domain_state
);
811 if (!trusted_domain_state
) {
812 return NT_STATUS_NO_MEMORY
;
814 trusted_domain_state
->policy
= policy_state
;
816 msg
= ldb_msg_new(mem_ctx
);
818 return NT_STATUS_NO_MEMORY
;
821 /* search for the trusted_domain record */
822 ret
= gendb_search(trusted_domain_state
->policy
->sam_ldb
,
823 mem_ctx
, policy_state
->system_dn
, &msgs
, attrs
,
824 "(&(cn=%s)(objectclass=trustedDomain))",
825 ldb_binary_encode_string(mem_ctx
, r
->in
.info
->name
.string
));
827 return NT_STATUS_OBJECT_NAME_COLLISION
;
830 if (ret
< 0 || ret
> 1) {
831 DEBUG(0,("Found %d records matching DN %s\n", ret
,
832 ldb_dn_linearize(mem_ctx
, policy_state
->system_dn
)));
833 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
836 msg
->dn
= ldb_dn_build_child(mem_ctx
, "cn",
837 r
->in
.info
->name
.string
,
838 policy_state
->system_dn
);
840 return NT_STATUS_NO_MEMORY
;
843 samdb_msg_add_string(trusted_domain_state
->policy
->sam_ldb
, mem_ctx
, msg
, "cn", name
);
844 samdb_msg_add_string(trusted_domain_state
->policy
->sam_ldb
, mem_ctx
, msg
, "flatname", name
);
846 if (r
->in
.info
->sid
) {
847 const char *sid_string
= dom_sid_string(mem_ctx
, r
->in
.info
->sid
);
849 return NT_STATUS_NO_MEMORY
;
852 samdb_msg_add_string(trusted_domain_state
->policy
->sam_ldb
, mem_ctx
, msg
, "securityIdentifier", sid_string
);
855 samdb_msg_add_string(trusted_domain_state
->policy
->sam_ldb
, mem_ctx
, msg
, "objectClass", "trustedDomain");
857 trusted_domain_state
->trusted_domain_dn
= talloc_reference(trusted_domain_state
, msg
->dn
);
859 /* create the trusted_domain */
860 ret
= ldb_add(trusted_domain_state
->policy
->sam_ldb
, msg
);
861 if (ret
!= LDB_SUCCESS
) {
862 DEBUG(0,("Failed to create trusted_domain record %s: %s\n",
863 ldb_dn_linearize(mem_ctx
, msg
->dn
), ldb_errstring(trusted_domain_state
->policy
->sam_ldb
)));
864 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
867 handle
= dcesrv_handle_new(dce_call
->context
, LSA_HANDLE_TRUSTED_DOMAIN
);
869 return NT_STATUS_NO_MEMORY
;
872 handle
->data
= talloc_steal(handle
, trusted_domain_state
);
874 trusted_domain_state
->access_mask
= r
->in
.access_mask
;
875 trusted_domain_state
->policy
= talloc_reference(trusted_domain_state
, policy_state
);
877 *r
->out
.trustdom_handle
= handle
->wire_handle
;
883 lsa_OpenTrustedDomain
885 static NTSTATUS
lsa_OpenTrustedDomain(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
886 struct lsa_OpenTrustedDomain
*r
)
888 struct dcesrv_handle
*policy_handle
;
890 struct lsa_policy_state
*policy_state
;
891 struct lsa_trusted_domain_state
*trusted_domain_state
;
892 struct dcesrv_handle
*handle
;
893 struct ldb_message
**msgs
;
894 const char *attrs
[] = {
898 const char *sid_string
;
901 DCESRV_PULL_HANDLE(policy_handle
, r
->in
.handle
, LSA_HANDLE_POLICY
);
902 ZERO_STRUCTP(r
->out
.trustdom_handle
);
903 policy_state
= policy_handle
->data
;
905 trusted_domain_state
= talloc(mem_ctx
, struct lsa_trusted_domain_state
);
906 if (!trusted_domain_state
) {
907 return NT_STATUS_NO_MEMORY
;
909 trusted_domain_state
->policy
= policy_state
;
911 sid_string
= dom_sid_string(mem_ctx
, r
->in
.sid
);
913 return NT_STATUS_NO_MEMORY
;
916 /* search for the trusted_domain record */
917 ret
= gendb_search(trusted_domain_state
->policy
->sam_ldb
,
918 mem_ctx
, policy_state
->system_dn
, &msgs
, attrs
,
919 "(&(securityIdentifier=%s)(objectclass=trustedDomain))",
922 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
926 DEBUG(0,("Found %d records matching DN %s\n", ret
,
927 ldb_dn_linearize(mem_ctx
, policy_state
->system_dn
)));
928 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
931 trusted_domain_state
->trusted_domain_dn
= talloc_reference(trusted_domain_state
, msgs
[0]->dn
);
933 handle
= dcesrv_handle_new(dce_call
->context
, LSA_HANDLE_TRUSTED_DOMAIN
);
935 return NT_STATUS_NO_MEMORY
;
938 handle
->data
= talloc_steal(handle
, trusted_domain_state
);
940 trusted_domain_state
->access_mask
= r
->in
.access_mask
;
941 trusted_domain_state
->policy
= talloc_reference(trusted_domain_state
, policy_state
);
943 *r
->out
.trustdom_handle
= handle
->wire_handle
;
950 lsa_OpenTrustedDomainByName
952 static NTSTATUS
lsa_OpenTrustedDomainByName(struct dcesrv_call_state
*dce_call
,
954 struct lsa_OpenTrustedDomainByName
*r
)
956 struct dcesrv_handle
*policy_handle
;
958 struct lsa_policy_state
*policy_state
;
959 struct lsa_trusted_domain_state
*trusted_domain_state
;
960 struct dcesrv_handle
*handle
;
961 struct ldb_message
**msgs
;
962 const char *attrs
[] = {
968 DCESRV_PULL_HANDLE(policy_handle
, r
->in
.handle
, LSA_HANDLE_POLICY
);
969 ZERO_STRUCTP(r
->out
.trustdom_handle
);
970 policy_state
= policy_handle
->data
;
972 if (!r
->in
.name
.string
) {
973 return NT_STATUS_INVALID_PARAMETER
;
976 trusted_domain_state
= talloc(mem_ctx
, struct lsa_trusted_domain_state
);
977 if (!trusted_domain_state
) {
978 return NT_STATUS_NO_MEMORY
;
980 trusted_domain_state
->policy
= policy_state
;
982 /* search for the trusted_domain record */
983 ret
= gendb_search(trusted_domain_state
->policy
->sam_ldb
,
984 mem_ctx
, policy_state
->system_dn
, &msgs
, attrs
,
985 "(&(flatname=%s)(objectclass=trustedDomain))",
986 ldb_binary_encode_string(mem_ctx
, r
->in
.name
.string
));
988 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
992 DEBUG(0,("Found %d records matching DN %s\n", ret
,
993 ldb_dn_linearize(mem_ctx
, policy_state
->system_dn
)));
994 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
997 trusted_domain_state
->trusted_domain_dn
= talloc_reference(trusted_domain_state
, msgs
[0]->dn
);
999 handle
= dcesrv_handle_new(dce_call
->context
, LSA_HANDLE_TRUSTED_DOMAIN
);
1001 return NT_STATUS_NO_MEMORY
;
1004 handle
->data
= talloc_steal(handle
, trusted_domain_state
);
1006 trusted_domain_state
->access_mask
= r
->in
.access_mask
;
1007 trusted_domain_state
->policy
= talloc_reference(trusted_domain_state
, policy_state
);
1009 *r
->out
.trustdom_handle
= handle
->wire_handle
;
1011 return NT_STATUS_OK
;
1017 lsa_SetTrustedDomainInfo
1019 static NTSTATUS
lsa_SetTrustedDomainInfo(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1020 struct lsa_SetTrustedDomainInfo
*r
)
1022 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
1028 lsa_SetInfomrationTrustedDomain
1030 static NTSTATUS
lsa_SetInformationTrustedDomain(struct dcesrv_call_state
*dce_call
,
1031 TALLOC_CTX
*mem_ctx
,
1032 struct lsa_SetInformationTrustedDomain
*r
)
1034 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
1039 lsa_DeleteTrustedDomain
1041 static NTSTATUS
lsa_DeleteTrustedDomain(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1042 struct lsa_DeleteTrustedDomain
*r
)
1045 struct lsa_OpenTrustedDomain open
;
1046 struct lsa_Delete
delete;
1047 struct dcesrv_handle
*h
;
1049 open
.in
.handle
= r
->in
.handle
;
1050 open
.in
.sid
= r
->in
.dom_sid
;
1051 open
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1052 open
.out
.trustdom_handle
= talloc(mem_ctx
, struct policy_handle
);
1053 if (!open
.out
.trustdom_handle
) {
1054 return NT_STATUS_NO_MEMORY
;
1056 status
= lsa_OpenTrustedDomain(dce_call
, mem_ctx
, &open
);
1057 if (!NT_STATUS_IS_OK(status
)) {
1061 DCESRV_PULL_HANDLE(h
, open
.out
.trustdom_handle
, DCESRV_HANDLE_ANY
);
1062 talloc_steal(mem_ctx
, h
);
1064 delete.in
.handle
= open
.out
.trustdom_handle
;
1065 status
= lsa_Delete(dce_call
, mem_ctx
, &delete);
1066 if (!NT_STATUS_IS_OK(status
)) {
1069 return NT_STATUS_OK
;
1072 static NTSTATUS
fill_trust_domain_ex(TALLOC_CTX
*mem_ctx
,
1073 struct ldb_message
*msg
,
1074 struct lsa_TrustDomainInfoInfoEx
*info_ex
)
1076 info_ex
->domain_name
.string
1077 = ldb_msg_find_attr_as_string(msg
, "trustPartner", NULL
);
1078 info_ex
->netbios_name
.string
1079 = ldb_msg_find_attr_as_string(msg
, "flatname", NULL
);
1081 = samdb_result_dom_sid(mem_ctx
, msg
, "securityIdentifier");
1082 info_ex
->trust_direction
1083 = ldb_msg_find_attr_as_int(msg
, "trustDirection", 0);
1085 = ldb_msg_find_attr_as_int(msg
, "trustType", 0);
1086 info_ex
->trust_attributes
1087 = ldb_msg_find_attr_as_int(msg
, "trustAttributes", 0);
1088 return NT_STATUS_OK
;
1092 lsa_QueryTrustedDomainInfo
1094 static NTSTATUS
lsa_QueryTrustedDomainInfo(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1095 struct lsa_QueryTrustedDomainInfo
*r
)
1097 struct dcesrv_handle
*h
;
1098 struct lsa_trusted_domain_state
*trusted_domain_state
;
1099 struct ldb_message
*msg
;
1101 struct ldb_message
**res
;
1102 const char *attrs
[] = {
1105 "securityIdentifier",
1112 DCESRV_PULL_HANDLE(h
, r
->in
.trustdom_handle
, LSA_HANDLE_TRUSTED_DOMAIN
);
1114 trusted_domain_state
= h
->data
;
1116 /* pull all the user attributes */
1117 ret
= gendb_search_dn(trusted_domain_state
->policy
->sam_ldb
, mem_ctx
,
1118 trusted_domain_state
->trusted_domain_dn
, &res
, attrs
);
1120 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1124 r
->out
.info
= talloc(mem_ctx
, union lsa_TrustedDomainInfo
);
1126 return NT_STATUS_NO_MEMORY
;
1128 switch (r
->in
.level
) {
1129 case LSA_TRUSTED_DOMAIN_INFO_NAME
:
1130 r
->out
.info
->name
.netbios_name
.string
1131 = samdb_result_string(msg
, "flatname", NULL
);
1133 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET
:
1134 r
->out
.info
->posix_offset
.posix_offset
1135 = samdb_result_uint(msg
, "posixOffset", 0);
1137 #if 0 /* Win2k3 doesn't implement this */
1138 case LSA_TRUSTED_DOMAIN_INFO_BASIC
:
1139 r
->out
.info
->info_basic
.netbios_name
.string
1140 = ldb_msg_find_attr_as_string(msg
, "flatname", NULL
);
1141 r
->out
.info
->info_basic
.sid
1142 = samdb_result_dom_sid(mem_ctx
, msg
, "securityIdentifier");
1145 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX
:
1146 return fill_trust_domain_ex(mem_ctx
, msg
, &r
->out
.info
->info_ex
);
1148 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO
:
1149 ZERO_STRUCT(r
->out
.info
->full_info
);
1150 return fill_trust_domain_ex(mem_ctx
, msg
, &r
->out
.info
->full_info
.info_ex
);
1152 case LSA_TRUSTED_DOMAIN_INFO_INFO_ALL
:
1153 ZERO_STRUCT(r
->out
.info
->info_all
);
1154 return fill_trust_domain_ex(mem_ctx
, msg
, &r
->out
.info
->info_all
.info_ex
);
1156 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS_INFO
:
1157 case LSA_TRUSTED_DOMAIN_INFO_11
:
1158 /* oops, we don't want to return the info after all */
1159 talloc_free(r
->out
.info
);
1161 return NT_STATUS_INVALID_PARAMETER
;
1163 /* oops, we don't want to return the info after all */
1164 talloc_free(r
->out
.info
);
1166 return NT_STATUS_INVALID_INFO_CLASS
;
1169 return NT_STATUS_OK
;
1174 lsa_QueryTrustedDomainInfoBySid
1176 static NTSTATUS
lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1177 struct lsa_QueryTrustedDomainInfoBySid
*r
)
1180 struct lsa_OpenTrustedDomain open
;
1181 struct lsa_QueryTrustedDomainInfo query
;
1182 struct dcesrv_handle
*h
;
1183 open
.in
.handle
= r
->in
.handle
;
1184 open
.in
.sid
= r
->in
.dom_sid
;
1185 open
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1186 open
.out
.trustdom_handle
= talloc(mem_ctx
, struct policy_handle
);
1187 if (!open
.out
.trustdom_handle
) {
1188 return NT_STATUS_NO_MEMORY
;
1190 status
= lsa_OpenTrustedDomain(dce_call
, mem_ctx
, &open
);
1191 if (!NT_STATUS_IS_OK(status
)) {
1195 /* Ensure this handle goes away at the end of this call */
1196 DCESRV_PULL_HANDLE(h
, open
.out
.trustdom_handle
, DCESRV_HANDLE_ANY
);
1197 talloc_steal(mem_ctx
, h
);
1199 query
.in
.trustdom_handle
= open
.out
.trustdom_handle
;
1200 query
.in
.level
= r
->in
.level
;
1201 status
= lsa_QueryTrustedDomainInfo(dce_call
, mem_ctx
, &query
);
1202 if (!NT_STATUS_IS_OK(status
)) {
1206 r
->out
.info
= query
.out
.info
;
1207 return NT_STATUS_OK
;
1211 lsa_SetTrustedDomainInfoByName
1213 static NTSTATUS
lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state
*dce_call
,
1214 TALLOC_CTX
*mem_ctx
,
1215 struct lsa_SetTrustedDomainInfoByName
*r
)
1217 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
1221 lsa_QueryTrustedDomainInfoByName
1223 static NTSTATUS
lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state
*dce_call
,
1224 TALLOC_CTX
*mem_ctx
,
1225 struct lsa_QueryTrustedDomainInfoByName
*r
)
1228 struct lsa_OpenTrustedDomainByName open
;
1229 struct lsa_QueryTrustedDomainInfo query
;
1230 struct dcesrv_handle
*h
;
1231 open
.in
.handle
= r
->in
.handle
;
1232 open
.in
.name
= r
->in
.trusted_domain
;
1233 open
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1234 open
.out
.trustdom_handle
= talloc(mem_ctx
, struct policy_handle
);
1235 if (!open
.out
.trustdom_handle
) {
1236 return NT_STATUS_NO_MEMORY
;
1238 status
= lsa_OpenTrustedDomainByName(dce_call
, mem_ctx
, &open
);
1239 if (!NT_STATUS_IS_OK(status
)) {
1243 /* Ensure this handle goes away at the end of this call */
1244 DCESRV_PULL_HANDLE(h
, open
.out
.trustdom_handle
, DCESRV_HANDLE_ANY
);
1245 talloc_steal(mem_ctx
, h
);
1247 query
.in
.trustdom_handle
= open
.out
.trustdom_handle
;
1248 query
.in
.level
= r
->in
.level
;
1249 status
= lsa_QueryTrustedDomainInfo(dce_call
, mem_ctx
, &query
);
1250 if (!NT_STATUS_IS_OK(status
)) {
1254 r
->out
.info
= query
.out
.info
;
1255 return NT_STATUS_OK
;
1259 lsa_CloseTrustedDomainEx
1261 static NTSTATUS
lsa_CloseTrustedDomainEx(struct dcesrv_call_state
*dce_call
,
1262 TALLOC_CTX
*mem_ctx
,
1263 struct lsa_CloseTrustedDomainEx
*r
)
1265 /* The result of a bad hair day from an IDL programmer? Not
1266 * implmented in Win2k3. You should always just lsa_Close
1268 return NT_STATUS_NOT_IMPLEMENTED
;
1273 comparison function for sorting lsa_DomainInformation array
1275 static int compare_DomainInfo(struct lsa_DomainInfo
*e1
, struct lsa_DomainInfo
*e2
)
1277 return strcasecmp_m(e1
->name
.string
, e2
->name
.string
);
1283 static NTSTATUS
lsa_EnumTrustDom(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1284 struct lsa_EnumTrustDom
*r
)
1286 struct dcesrv_handle
*policy_handle
;
1287 struct lsa_DomainInfo
*entries
;
1288 struct lsa_policy_state
*policy_state
;
1289 struct ldb_message
**domains
;
1290 const char *attrs
[] = {
1292 "securityIdentifier",
1299 *r
->out
.resume_handle
= 0;
1301 r
->out
.domains
->domains
= NULL
;
1302 r
->out
.domains
->count
= 0;
1304 DCESRV_PULL_HANDLE(policy_handle
, r
->in
.handle
, LSA_HANDLE_POLICY
);
1306 policy_state
= policy_handle
->data
;
1308 /* search for all users in this domain. This could possibly be cached and
1309 resumed based on resume_key */
1310 count
= gendb_search(policy_state
->sam_ldb
, mem_ctx
, policy_state
->system_dn
, &domains
, attrs
,
1311 "objectclass=trustedDomain");
1313 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1315 if (count
== 0 || r
->in
.max_size
== 0) {
1316 return NT_STATUS_OK
;
1319 /* convert to lsa_TrustInformation format */
1320 entries
= talloc_array(mem_ctx
, struct lsa_DomainInfo
, count
);
1322 return NT_STATUS_NO_MEMORY
;
1324 for (i
=0;i
<count
;i
++) {
1325 entries
[i
].sid
= samdb_result_dom_sid(mem_ctx
, domains
[i
], "securityIdentifier");
1326 entries
[i
].name
.string
= samdb_result_string(domains
[i
], "flatname", NULL
);
1329 /* sort the results by name */
1330 qsort(entries
, count
, sizeof(*entries
),
1331 (comparison_fn_t
)compare_DomainInfo
);
1333 if (*r
->in
.resume_handle
>= count
) {
1334 *r
->out
.resume_handle
= -1;
1336 return NT_STATUS_NO_MORE_ENTRIES
;
1339 /* return the rest, limit by max_size. Note that we
1340 use the w2k3 element size value of 60 */
1341 r
->out
.domains
->count
= count
- *r
->in
.resume_handle
;
1342 r
->out
.domains
->count
= MIN(r
->out
.domains
->count
,
1343 1+(r
->in
.max_size
/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER
));
1345 r
->out
.domains
->domains
= entries
+ *r
->in
.resume_handle
;
1346 r
->out
.domains
->count
= r
->out
.domains
->count
;
1348 if (r
->out
.domains
->count
< count
- *r
->in
.resume_handle
) {
1349 *r
->out
.resume_handle
= *r
->in
.resume_handle
+ r
->out
.domains
->count
;
1350 return STATUS_MORE_ENTRIES
;
1353 return NT_STATUS_OK
;
1357 comparison function for sorting lsa_DomainInformation array
1359 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx
*e1
, struct lsa_TrustDomainInfoInfoEx
*e2
)
1361 return strcasecmp_m(e1
->netbios_name
.string
, e2
->netbios_name
.string
);
1365 lsa_EnumTrustedDomainsEx
1367 static NTSTATUS
lsa_EnumTrustedDomainsEx(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1368 struct lsa_EnumTrustedDomainsEx
*r
)
1370 struct dcesrv_handle
*policy_handle
;
1371 struct lsa_TrustDomainInfoInfoEx
*entries
;
1372 struct lsa_policy_state
*policy_state
;
1373 struct ldb_message
**domains
;
1374 const char *attrs
[] = {
1377 "securityIdentifier",
1387 *r
->out
.resume_handle
= 0;
1389 r
->out
.domains
->domains
= NULL
;
1390 r
->out
.domains
->count
= 0;
1392 DCESRV_PULL_HANDLE(policy_handle
, r
->in
.handle
, LSA_HANDLE_POLICY
);
1394 policy_state
= policy_handle
->data
;
1396 /* search for all users in this domain. This could possibly be cached and
1397 resumed based on resume_key */
1398 count
= gendb_search(policy_state
->sam_ldb
, mem_ctx
, policy_state
->system_dn
, &domains
, attrs
,
1399 "objectclass=trustedDomain");
1401 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1403 if (count
== 0 || r
->in
.max_size
== 0) {
1404 return NT_STATUS_OK
;
1407 /* convert to lsa_DomainInformation format */
1408 entries
= talloc_array(mem_ctx
, struct lsa_TrustDomainInfoInfoEx
, count
);
1410 return NT_STATUS_NO_MEMORY
;
1412 for (i
=0;i
<count
;i
++) {
1413 nt_status
= fill_trust_domain_ex(mem_ctx
, domains
[i
], &entries
[i
]);
1414 if (!NT_STATUS_IS_OK(nt_status
)) {
1419 /* sort the results by name */
1420 qsort(entries
, count
, sizeof(*entries
),
1421 (comparison_fn_t
)compare_TrustDomainInfoInfoEx
);
1423 if (*r
->in
.resume_handle
>= count
) {
1424 *r
->out
.resume_handle
= -1;
1426 return NT_STATUS_NO_MORE_ENTRIES
;
1429 /* return the rest, limit by max_size. Note that we
1430 use the w2k3 element size value of 60 */
1431 r
->out
.domains
->count
= count
- *r
->in
.resume_handle
;
1432 r
->out
.domains
->count
= MIN(r
->out
.domains
->count
,
1433 1+(r
->in
.max_size
/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER
));
1435 r
->out
.domains
->domains
= entries
+ *r
->in
.resume_handle
;
1436 r
->out
.domains
->count
= r
->out
.domains
->count
;
1438 if (r
->out
.domains
->count
< count
- *r
->in
.resume_handle
) {
1439 *r
->out
.resume_handle
= *r
->in
.resume_handle
+ r
->out
.domains
->count
;
1440 return STATUS_MORE_ENTRIES
;
1443 return NT_STATUS_OK
;
1448 return the authority name and authority sid, given a sid
1450 static NTSTATUS
lsa_authority_name(struct lsa_policy_state
*state
,
1451 TALLOC_CTX
*mem_ctx
, struct dom_sid
*sid
,
1452 const char **authority_name
,
1453 struct dom_sid
**authority_sid
)
1455 if (dom_sid_in_domain(state
->domain_sid
, sid
)) {
1456 *authority_name
= state
->domain_name
;
1457 *authority_sid
= state
->domain_sid
;
1458 return NT_STATUS_OK
;
1461 if (dom_sid_in_domain(state
->builtin_sid
, sid
)) {
1462 *authority_name
= "BUILTIN";
1463 *authority_sid
= state
->builtin_sid
;
1464 return NT_STATUS_OK
;
1467 *authority_sid
= dom_sid_dup(mem_ctx
, sid
);
1468 if (*authority_sid
== NULL
) {
1469 return NT_STATUS_NO_MEMORY
;
1471 (*authority_sid
)->num_auths
= 0;
1472 *authority_name
= dom_sid_string(mem_ctx
, *authority_sid
);
1473 if (*authority_name
== NULL
) {
1474 return NT_STATUS_NO_MEMORY
;
1477 return NT_STATUS_OK
;
1481 add to the lsa_RefDomainList for LookupSids and LookupNames
1483 static NTSTATUS
lsa_authority_list(struct lsa_policy_state
*state
, TALLOC_CTX
*mem_ctx
,
1484 struct dom_sid
*sid
,
1485 struct lsa_RefDomainList
*domains
,
1486 uint32_t *sid_index
)
1489 const char *authority_name
;
1490 struct dom_sid
*authority_sid
;
1493 /* work out the authority name */
1494 status
= lsa_authority_name(state
, mem_ctx
, sid
,
1495 &authority_name
, &authority_sid
);
1496 if (!NT_STATUS_IS_OK(status
)) {
1500 /* see if we've already done this authority name */
1501 for (i
=0;i
<domains
->count
;i
++) {
1502 if (strcmp(authority_name
, domains
->domains
[i
].name
.string
) == 0) {
1504 return NT_STATUS_OK
;
1508 domains
->domains
= talloc_realloc(domains
,
1510 struct lsa_DomainInfo
,
1512 if (domains
->domains
== NULL
) {
1513 return NT_STATUS_NO_MEMORY
;
1515 domains
->domains
[i
].name
.string
= authority_name
;
1516 domains
->domains
[i
].sid
= authority_sid
;
1518 domains
->max_size
= LSA_REF_DOMAIN_LIST_MULTIPLIER
* domains
->count
;
1521 return NT_STATUS_OK
;
1525 lookup a name for 1 SID
1527 static NTSTATUS
lsa_lookup_sid(struct lsa_policy_state
*state
, TALLOC_CTX
*mem_ctx
,
1528 struct dom_sid
*sid
, const char *sid_str
,
1529 const char **name
, uint32_t *atype
)
1532 struct ldb_message
**res
;
1533 const char * const attrs
[] = { "sAMAccountName", "sAMAccountType", "name", NULL
};
1536 ret
= gendb_search(state
->sam_ldb
, mem_ctx
, NULL
, &res
, attrs
,
1537 "objectSid=%s", ldap_encode_ndr_dom_sid(mem_ctx
, sid
));
1539 *name
= ldb_msg_find_attr_as_string(res
[0], "sAMAccountName", NULL
);
1541 *name
= ldb_msg_find_attr_as_string(res
[0], "name", NULL
);
1543 *name
= talloc_strdup(mem_ctx
, sid_str
);
1544 NT_STATUS_HAVE_NO_MEMORY(*name
);
1548 *atype
= samdb_result_uint(res
[0], "sAMAccountType", 0);
1550 return NT_STATUS_OK
;
1553 status
= sidmap_allocated_sid_lookup(state
->sidmap
, mem_ctx
, sid
, name
, atype
);
1562 static NTSTATUS
lsa_LookupSids2(struct dcesrv_call_state
*dce_call
,
1563 TALLOC_CTX
*mem_ctx
,
1564 struct lsa_LookupSids2
*r
)
1566 struct lsa_policy_state
*state
;
1568 NTSTATUS status
= NT_STATUS_OK
;
1570 r
->out
.domains
= NULL
;
1572 status
= lsa_get_policy_state(dce_call
, mem_ctx
, &state
);
1573 if (!NT_STATUS_IS_OK(status
)) {
1577 r
->out
.domains
= talloc_zero(mem_ctx
, struct lsa_RefDomainList
);
1578 if (r
->out
.domains
== NULL
) {
1579 return NT_STATUS_NO_MEMORY
;
1582 r
->out
.names
= talloc_zero(mem_ctx
, struct lsa_TransNameArray2
);
1583 if (r
->out
.names
== NULL
) {
1584 return NT_STATUS_NO_MEMORY
;
1589 r
->out
.names
->names
= talloc_array(r
->out
.names
, struct lsa_TranslatedName2
,
1590 r
->in
.sids
->num_sids
);
1591 if (r
->out
.names
->names
== NULL
) {
1592 return NT_STATUS_NO_MEMORY
;
1595 for (i
=0;i
<r
->in
.sids
->num_sids
;i
++) {
1596 struct dom_sid
*sid
= r
->in
.sids
->sids
[i
].sid
;
1597 char *sid_str
= dom_sid_string(mem_ctx
, sid
);
1599 uint32_t atype
, rtype
, sid_index
;
1602 r
->out
.names
->count
++;
1605 r
->out
.names
->names
[i
].sid_type
= SID_NAME_UNKNOWN
;
1606 r
->out
.names
->names
[i
].name
.string
= sid_str
;
1607 r
->out
.names
->names
[i
].sid_index
= 0xFFFFFFFF;
1608 r
->out
.names
->names
[i
].unknown
= 0;
1610 if (sid_str
== NULL
) {
1611 r
->out
.names
->names
[i
].name
.string
= "(SIDERROR)";
1612 status
= STATUS_SOME_UNMAPPED
;
1616 /* work out the authority name */
1617 status2
= lsa_authority_list(state
, mem_ctx
, sid
, r
->out
.domains
, &sid_index
);
1618 if (!NT_STATUS_IS_OK(status2
)) {
1622 status2
= lsa_lookup_sid(state
, mem_ctx
, sid
, sid_str
,
1624 if (!NT_STATUS_IS_OK(status2
)) {
1625 status
= STATUS_SOME_UNMAPPED
;
1629 rtype
= samdb_atype_map(atype
);
1630 if (rtype
== SID_NAME_UNKNOWN
) {
1631 status
= STATUS_SOME_UNMAPPED
;
1635 r
->out
.names
->names
[i
].sid_type
= rtype
;
1636 r
->out
.names
->names
[i
].name
.string
= name
;
1637 r
->out
.names
->names
[i
].sid_index
= sid_index
;
1638 r
->out
.names
->names
[i
].unknown
= 0;
1648 Identical to LookupSids2, but doesn't take a policy handle
1651 static NTSTATUS
lsa_LookupSids3(struct dcesrv_call_state
*dce_call
,
1652 TALLOC_CTX
*mem_ctx
,
1653 struct lsa_LookupSids3
*r
)
1655 struct lsa_LookupSids2 r2
;
1656 struct lsa_OpenPolicy2 pol
;
1658 struct dcesrv_handle
*h
;
1660 /* No policy handle on the wire, so make one up here */
1661 r2
.in
.handle
= talloc(mem_ctx
, struct policy_handle
);
1662 if (!r2
.in
.handle
) {
1663 return NT_STATUS_NO_MEMORY
;
1666 pol
.out
.handle
= r2
.in
.handle
;
1667 pol
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1669 pol
.in
.system_name
= NULL
;
1670 status
= lsa_OpenPolicy2(dce_call
, mem_ctx
, &pol
);
1671 if (!NT_STATUS_IS_OK(status
)) {
1675 /* ensure this handle goes away at the end of this call */
1676 DCESRV_PULL_HANDLE(h
, r2
.in
.handle
, LSA_HANDLE_POLICY
);
1677 talloc_steal(mem_ctx
, h
);
1679 r2
.in
.sids
= r
->in
.sids
;
1680 r2
.in
.names
= r
->in
.names
;
1681 r2
.in
.level
= r
->in
.level
;
1682 r2
.in
.count
= r
->in
.count
;
1683 r2
.in
.unknown1
= r
->in
.unknown1
;
1684 r2
.in
.unknown2
= r
->in
.unknown2
;
1685 r2
.out
.count
= r
->out
.count
;
1686 r2
.out
.names
= r
->out
.names
;
1688 status
= lsa_LookupSids2(dce_call
, mem_ctx
, &r2
);
1689 if (dce_call
->fault_code
!= 0) {
1693 r
->out
.domains
= r2
.out
.domains
;
1694 r
->out
.names
= r2
.out
.names
;
1695 r
->out
.count
= r2
.out
.count
;
1704 static NTSTATUS
lsa_LookupSids(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1705 struct lsa_LookupSids
*r
)
1707 struct lsa_LookupSids2 r2
;
1711 r2
.in
.handle
= r
->in
.handle
;
1712 r2
.in
.sids
= r
->in
.sids
;
1714 r2
.in
.level
= r
->in
.level
;
1715 r2
.in
.count
= r
->in
.count
;
1718 r2
.out
.count
= r
->out
.count
;
1719 r2
.out
.names
= NULL
;
1721 status
= lsa_LookupSids2(dce_call
, mem_ctx
, &r2
);
1722 if (dce_call
->fault_code
!= 0) {
1726 r
->out
.domains
= r2
.out
.domains
;
1727 if (!r2
.out
.names
) {
1728 r
->out
.names
= NULL
;
1732 r
->out
.names
= talloc(mem_ctx
, struct lsa_TransNameArray
);
1733 if (r
->out
.names
== NULL
) {
1734 return NT_STATUS_NO_MEMORY
;
1736 r
->out
.names
->count
= r2
.out
.names
->count
;
1737 r
->out
.names
->names
= talloc_array(r
->out
.names
, struct lsa_TranslatedName
,
1738 r
->out
.names
->count
);
1739 if (r
->out
.names
->names
== NULL
) {
1740 return NT_STATUS_NO_MEMORY
;
1742 for (i
=0;i
<r
->out
.names
->count
;i
++) {
1743 r
->out
.names
->names
[i
].sid_type
= r2
.out
.names
->names
[i
].sid_type
;
1744 r
->out
.names
->names
[i
].name
.string
= r2
.out
.names
->names
[i
].name
.string
;
1745 r
->out
.names
->names
[i
].sid_index
= r2
.out
.names
->names
[i
].sid_index
;
1755 static NTSTATUS
lsa_OpenAccount(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1756 struct lsa_OpenAccount
*r
)
1758 struct dcesrv_handle
*h
, *ah
;
1759 struct lsa_policy_state
*state
;
1760 struct lsa_account_state
*astate
;
1762 ZERO_STRUCTP(r
->out
.acct_handle
);
1764 DCESRV_PULL_HANDLE(h
, r
->in
.handle
, LSA_HANDLE_POLICY
);
1768 astate
= talloc(dce_call
->conn
, struct lsa_account_state
);
1769 if (astate
== NULL
) {
1770 return NT_STATUS_NO_MEMORY
;
1773 astate
->account_sid
= dom_sid_dup(astate
, r
->in
.sid
);
1774 if (astate
->account_sid
== NULL
) {
1775 talloc_free(astate
);
1776 return NT_STATUS_NO_MEMORY
;
1779 astate
->policy
= talloc_reference(astate
, state
);
1780 astate
->access_mask
= r
->in
.access_mask
;
1782 ah
= dcesrv_handle_new(dce_call
->context
, LSA_HANDLE_ACCOUNT
);
1784 talloc_free(astate
);
1785 return NT_STATUS_NO_MEMORY
;
1788 ah
->data
= talloc_steal(ah
, astate
);
1790 *r
->out
.acct_handle
= ah
->wire_handle
;
1792 return NT_STATUS_OK
;
1797 lsa_EnumPrivsAccount
1799 static NTSTATUS
lsa_EnumPrivsAccount(struct dcesrv_call_state
*dce_call
,
1800 TALLOC_CTX
*mem_ctx
,
1801 struct lsa_EnumPrivsAccount
*r
)
1803 struct dcesrv_handle
*h
;
1804 struct lsa_account_state
*astate
;
1806 struct ldb_message
**res
;
1807 const char * const attrs
[] = { "privilege", NULL
};
1808 struct ldb_message_element
*el
;
1811 DCESRV_PULL_HANDLE(h
, r
->in
.handle
, LSA_HANDLE_ACCOUNT
);
1815 r
->out
.privs
= talloc(mem_ctx
, struct lsa_PrivilegeSet
);
1816 r
->out
.privs
->count
= 0;
1817 r
->out
.privs
->unknown
= 0;
1818 r
->out
.privs
->set
= NULL
;
1820 sidstr
= ldap_encode_ndr_dom_sid(mem_ctx
, astate
->account_sid
);
1821 if (sidstr
== NULL
) {
1822 return NT_STATUS_NO_MEMORY
;
1825 ret
= gendb_search(astate
->policy
->sam_ldb
, mem_ctx
, NULL
, &res
, attrs
,
1826 "objectSid=%s", sidstr
);
1828 return NT_STATUS_OK
;
1831 el
= ldb_msg_find_element(res
[0], "privilege");
1832 if (el
== NULL
|| el
->num_values
== 0) {
1833 return NT_STATUS_OK
;
1836 r
->out
.privs
->set
= talloc_array(r
->out
.privs
,
1837 struct lsa_LUIDAttribute
, el
->num_values
);
1838 if (r
->out
.privs
->set
== NULL
) {
1839 return NT_STATUS_NO_MEMORY
;
1842 for (i
=0;i
<el
->num_values
;i
++) {
1843 int id
= sec_privilege_id((const char *)el
->values
[i
].data
);
1845 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1847 r
->out
.privs
->set
[i
].attribute
= 0;
1848 r
->out
.privs
->set
[i
].luid
.low
= id
;
1849 r
->out
.privs
->set
[i
].luid
.high
= 0;
1852 r
->out
.privs
->count
= el
->num_values
;
1854 return NT_STATUS_OK
;
1858 lsa_EnumAccountRights
1860 static NTSTATUS
lsa_EnumAccountRights(struct dcesrv_call_state
*dce_call
,
1861 TALLOC_CTX
*mem_ctx
,
1862 struct lsa_EnumAccountRights
*r
)
1864 struct dcesrv_handle
*h
;
1865 struct lsa_policy_state
*state
;
1867 struct ldb_message
**res
;
1868 const char * const attrs
[] = { "privilege", NULL
};
1870 struct ldb_message_element
*el
;
1872 DCESRV_PULL_HANDLE(h
, r
->in
.handle
, LSA_HANDLE_POLICY
);
1876 sidstr
= ldap_encode_ndr_dom_sid(mem_ctx
, r
->in
.sid
);
1877 if (sidstr
== NULL
) {
1878 return NT_STATUS_NO_MEMORY
;
1881 ret
= gendb_search(state
->sam_ldb
, mem_ctx
, NULL
, &res
, attrs
,
1882 "(&(objectSid=%s)(privilege=*))", sidstr
);
1884 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1887 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1890 DEBUG(3, ("searching for account rights for SID: %s failed: %s",
1891 dom_sid_string(mem_ctx
, r
->in
.sid
),
1892 ldb_errstring(state
->sam_ldb
)));
1893 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1896 el
= ldb_msg_find_element(res
[0], "privilege");
1897 if (el
== NULL
|| el
->num_values
== 0) {
1898 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1901 r
->out
.rights
->count
= el
->num_values
;
1902 r
->out
.rights
->names
= talloc_array(r
->out
.rights
,
1903 struct lsa_StringLarge
, r
->out
.rights
->count
);
1904 if (r
->out
.rights
->names
== NULL
) {
1905 return NT_STATUS_NO_MEMORY
;
1908 for (i
=0;i
<el
->num_values
;i
++) {
1909 r
->out
.rights
->names
[i
].string
= (const char *)el
->values
[i
].data
;
1912 return NT_STATUS_OK
;
1918 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
1920 static NTSTATUS
lsa_AddRemoveAccountRights(struct dcesrv_call_state
*dce_call
,
1921 TALLOC_CTX
*mem_ctx
,
1922 struct lsa_policy_state
*state
,
1924 struct dom_sid
*sid
,
1925 const struct lsa_RightSet
*rights
)
1928 struct ldb_message
*msg
;
1929 struct ldb_message_element
*el
;
1931 struct lsa_EnumAccountRights r2
;
1933 sidstr
= ldap_encode_ndr_dom_sid(mem_ctx
, sid
);
1934 if (sidstr
== NULL
) {
1935 return NT_STATUS_NO_MEMORY
;
1938 msg
= ldb_msg_new(mem_ctx
);
1940 return NT_STATUS_NO_MEMORY
;
1943 msg
->dn
= samdb_search_dn(state
->sam_ldb
, mem_ctx
,
1944 NULL
, "objectSid=%s", sidstr
);
1945 if (msg
->dn
== NULL
) {
1947 if (ldb_flag
== LDB_FLAG_MOD_DELETE
) {
1948 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1950 status
= samdb_create_foreign_security_principal(state
->sam_ldb
, mem_ctx
,
1952 if (!NT_STATUS_IS_OK(status
)) {
1955 return NT_STATUS_NO_SUCH_USER
;
1958 if (ldb_msg_add_empty(msg
, "privilege", ldb_flag
, NULL
)) {
1959 return NT_STATUS_NO_MEMORY
;
1962 if (ldb_flag
== LDB_FLAG_MOD_ADD
) {
1965 r2
.in
.handle
= &state
->handle
->wire_handle
;
1967 r2
.out
.rights
= talloc(mem_ctx
, struct lsa_RightSet
);
1969 status
= lsa_EnumAccountRights(dce_call
, mem_ctx
, &r2
);
1970 if (!NT_STATUS_IS_OK(status
)) {
1971 ZERO_STRUCTP(r2
.out
.rights
);
1975 for (i
=0;i
<rights
->count
;i
++) {
1976 if (sec_privilege_id(rights
->names
[i
].string
) == -1) {
1977 return NT_STATUS_NO_SUCH_PRIVILEGE
;
1980 if (ldb_flag
== LDB_FLAG_MOD_ADD
) {
1982 for (j
=0;j
<r2
.out
.rights
->count
;j
++) {
1983 if (strcasecmp_m(r2
.out
.rights
->names
[j
].string
,
1984 rights
->names
[i
].string
) == 0) {
1988 if (j
!= r2
.out
.rights
->count
) continue;
1991 ret
= ldb_msg_add_string(msg
, "privilege", rights
->names
[i
].string
);
1992 if (ret
!= LDB_SUCCESS
) {
1993 return NT_STATUS_NO_MEMORY
;
1997 el
= ldb_msg_find_element(msg
, "privilege");
1999 return NT_STATUS_OK
;
2002 ret
= samdb_modify(state
->sam_ldb
, mem_ctx
, msg
);
2004 if (ldb_flag
== LDB_FLAG_MOD_DELETE
&& ret
== LDB_ERR_NO_SUCH_ATTRIBUTE
) {
2005 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2007 DEBUG(3, ("Could not %s attributes from %s: %s",
2008 ldb_flag
== LDB_FLAG_MOD_DELETE
? "delete" : "add",
2009 ldb_dn_linearize(mem_ctx
, msg
->dn
), ldb_errstring(state
->sam_ldb
)));
2010 return NT_STATUS_UNEXPECTED_IO_ERROR
;
2013 return NT_STATUS_OK
;
2017 lsa_AddPrivilegesToAccount
2019 static NTSTATUS
lsa_AddPrivilegesToAccount(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
2020 struct lsa_AddPrivilegesToAccount
*r
)
2022 struct lsa_RightSet rights
;
2023 struct dcesrv_handle
*h
;
2024 struct lsa_account_state
*astate
;
2027 DCESRV_PULL_HANDLE(h
, r
->in
.handle
, LSA_HANDLE_ACCOUNT
);
2031 rights
.count
= r
->in
.privs
->count
;
2032 rights
.names
= talloc_array(mem_ctx
, struct lsa_StringLarge
, rights
.count
);
2033 if (rights
.names
== NULL
) {
2034 return NT_STATUS_NO_MEMORY
;
2036 for (i
=0;i
<rights
.count
;i
++) {
2037 int id
= r
->in
.privs
->set
[i
].luid
.low
;
2038 if (r
->in
.privs
->set
[i
].luid
.high
) {
2039 return NT_STATUS_NO_SUCH_PRIVILEGE
;
2041 rights
.names
[i
].string
= sec_privilege_name(id
);
2042 if (rights
.names
[i
].string
== NULL
) {
2043 return NT_STATUS_NO_SUCH_PRIVILEGE
;
2047 return lsa_AddRemoveAccountRights(dce_call
, mem_ctx
, astate
->policy
,
2048 LDB_FLAG_MOD_ADD
, astate
->account_sid
,
2054 lsa_RemovePrivilegesFromAccount
2056 static NTSTATUS
lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
2057 struct lsa_RemovePrivilegesFromAccount
*r
)
2059 struct lsa_RightSet
*rights
;
2060 struct dcesrv_handle
*h
;
2061 struct lsa_account_state
*astate
;
2064 DCESRV_PULL_HANDLE(h
, r
->in
.handle
, LSA_HANDLE_ACCOUNT
);
2068 rights
= talloc(mem_ctx
, struct lsa_RightSet
);
2070 if (r
->in
.remove_all
== 1 &&
2071 r
->in
.privs
== NULL
) {
2072 struct lsa_EnumAccountRights r2
;
2075 r2
.in
.handle
= &astate
->policy
->handle
->wire_handle
;
2076 r2
.in
.sid
= astate
->account_sid
;
2077 r2
.out
.rights
= rights
;
2079 status
= lsa_EnumAccountRights(dce_call
, mem_ctx
, &r2
);
2080 if (!NT_STATUS_IS_OK(status
)) {
2084 return lsa_AddRemoveAccountRights(dce_call
, mem_ctx
, astate
->policy
,
2085 LDB_FLAG_MOD_DELETE
, astate
->account_sid
,
2089 if (r
->in
.remove_all
!= 0) {
2090 return NT_STATUS_INVALID_PARAMETER
;
2093 rights
->count
= r
->in
.privs
->count
;
2094 rights
->names
= talloc_array(mem_ctx
, struct lsa_StringLarge
, rights
->count
);
2095 if (rights
->names
== NULL
) {
2096 return NT_STATUS_NO_MEMORY
;
2098 for (i
=0;i
<rights
->count
;i
++) {
2099 int id
= r
->in
.privs
->set
[i
].luid
.low
;
2100 if (r
->in
.privs
->set
[i
].luid
.high
) {
2101 return NT_STATUS_NO_SUCH_PRIVILEGE
;
2103 rights
->names
[i
].string
= sec_privilege_name(id
);
2104 if (rights
->names
[i
].string
== NULL
) {
2105 return NT_STATUS_NO_SUCH_PRIVILEGE
;
2109 return lsa_AddRemoveAccountRights(dce_call
, mem_ctx
, astate
->policy
,
2110 LDB_FLAG_MOD_DELETE
, astate
->account_sid
,
2116 lsa_GetQuotasForAccount
2118 static NTSTATUS
lsa_GetQuotasForAccount(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
2119 struct lsa_GetQuotasForAccount
*r
)
2121 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
2126 lsa_SetQuotasForAccount
2128 static NTSTATUS
lsa_SetQuotasForAccount(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
2129 struct lsa_SetQuotasForAccount
*r
)
2131 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
2136 lsa_GetSystemAccessAccount
2138 static NTSTATUS
lsa_GetSystemAccessAccount(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
2139 struct lsa_GetSystemAccessAccount
*r
)
2141 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
2146 lsa_SetSystemAccessAccount
2148 static NTSTATUS
lsa_SetSystemAccessAccount(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
2149 struct lsa_SetSystemAccessAccount
*r
)
2151 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
2158 static NTSTATUS
lsa_CreateSecret(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
2159 struct lsa_CreateSecret
*r
)
2161 struct dcesrv_handle
*policy_handle
;
2162 struct lsa_policy_state
*policy_state
;
2163 struct lsa_secret_state
*secret_state
;
2164 struct dcesrv_handle
*handle
;
2165 struct ldb_message
**msgs
, *msg
;
2167 const char *attrs
[] = {
2175 DCESRV_PULL_HANDLE(policy_handle
, r
->in
.handle
, LSA_HANDLE_POLICY
);
2176 ZERO_STRUCTP(r
->out
.sec_handle
);
2178 policy_state
= policy_handle
->data
;
2180 if (!r
->in
.name
.string
) {
2181 return NT_STATUS_INVALID_PARAMETER
;
2184 secret_state
= talloc(mem_ctx
, struct lsa_secret_state
);
2185 if (!secret_state
) {
2186 return NT_STATUS_NO_MEMORY
;
2188 secret_state
->policy
= policy_state
;
2190 msg
= ldb_msg_new(mem_ctx
);
2192 return NT_STATUS_NO_MEMORY
;
2195 if (strncmp("G$", r
->in
.name
.string
, 2) == 0) {
2197 name
= &r
->in
.name
.string
[2];
2198 secret_state
->sam_ldb
= talloc_reference(secret_state
, policy_state
->sam_ldb
);
2199 secret_state
->global
= True
;
2201 if (strlen(name
) < 1) {
2202 return NT_STATUS_INVALID_PARAMETER
;
2205 name2
= talloc_asprintf(mem_ctx
, "%s Secret", ldb_binary_encode_string(mem_ctx
, name
));
2206 /* search for the secret record */
2207 ret
= gendb_search(secret_state
->sam_ldb
,
2208 mem_ctx
, policy_state
->system_dn
, &msgs
, attrs
,
2209 "(&(cn=%s)(objectclass=secret))",
2212 return NT_STATUS_OBJECT_NAME_COLLISION
;
2216 DEBUG(0,("Failure searching for CN=%s: %s\n",
2217 name2
, ldb_errstring(secret_state
->sam_ldb
)));
2218 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
2221 msg
->dn
= ldb_dn_build_child(mem_ctx
, "cn", name2
, policy_state
->system_dn
);
2222 if (!name2
|| !msg
->dn
) {
2223 return NT_STATUS_NO_MEMORY
;
2226 samdb_msg_add_string(secret_state
->sam_ldb
, mem_ctx
, msg
, "cn", name2
);
2229 secret_state
->global
= False
;
2231 name
= r
->in
.name
.string
;
2232 if (strlen(name
) < 1) {
2233 return NT_STATUS_INVALID_PARAMETER
;
2236 secret_state
->sam_ldb
= talloc_reference(secret_state
, secrets_db_connect(mem_ctx
));
2237 /* search for the secret record */
2238 ret
= gendb_search(secret_state
->sam_ldb
, mem_ctx
,
2239 ldb_dn_explode(mem_ctx
, "cn=LSA Secrets"),
2241 "(&(cn=%s)(objectclass=secret))",
2242 ldb_binary_encode_string(mem_ctx
, name
));
2244 return NT_STATUS_OBJECT_NAME_COLLISION
;
2248 DEBUG(0,("Failure searching for CN=%s: %s\n",
2249 name
, ldb_errstring(secret_state
->sam_ldb
)));
2250 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
2253 msg
->dn
= ldb_dn_string_compose(mem_ctx
, NULL
, "cn=%s,cn=LSA Secrets", name
);
2254 samdb_msg_add_string(secret_state
->sam_ldb
, mem_ctx
, msg
, "cn", name
);
2257 /* pull in all the template attributes. Note this is always from the global samdb */
2258 ret
= samdb_copy_template(secret_state
->policy
->sam_ldb
, msg
,
2259 "(&(cn=TemplateSecret)(objectclass=secretTemplate))", &errstr
);
2261 DEBUG(0,("Failed to load TemplateSecret from samdb: %s\n",
2263 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
2266 samdb_msg_add_string(secret_state
->sam_ldb
, mem_ctx
, msg
, "objectClass", "secret");
2268 secret_state
->secret_dn
= talloc_reference(secret_state
, msg
->dn
);
2270 /* create the secret */
2271 ret
= samdb_add(secret_state
->sam_ldb
, mem_ctx
, msg
);
2273 DEBUG(0,("Failed to create secret record %s: %s\n",
2274 ldb_dn_linearize(mem_ctx
, msg
->dn
),
2275 ldb_errstring(secret_state
->sam_ldb
)));
2276 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
2279 handle
= dcesrv_handle_new(dce_call
->context
, LSA_HANDLE_SECRET
);
2281 return NT_STATUS_NO_MEMORY
;
2284 handle
->data
= talloc_steal(handle
, secret_state
);
2286 secret_state
->access_mask
= r
->in
.access_mask
;
2287 secret_state
->policy
= talloc_reference(secret_state
, policy_state
);
2289 *r
->out
.sec_handle
= handle
->wire_handle
;
2291 return NT_STATUS_OK
;
2298 static NTSTATUS
lsa_OpenSecret(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
2299 struct lsa_OpenSecret
*r
)
2301 struct dcesrv_handle
*policy_handle
;
2303 struct lsa_policy_state
*policy_state
;
2304 struct lsa_secret_state
*secret_state
;
2305 struct dcesrv_handle
*handle
;
2306 struct ldb_message
**msgs
;
2307 const char *attrs
[] = {
2315 DCESRV_PULL_HANDLE(policy_handle
, r
->in
.handle
, LSA_HANDLE_POLICY
);
2316 ZERO_STRUCTP(r
->out
.sec_handle
);
2317 policy_state
= policy_handle
->data
;
2319 if (!r
->in
.name
.string
) {
2320 return NT_STATUS_INVALID_PARAMETER
;
2323 secret_state
= talloc(mem_ctx
, struct lsa_secret_state
);
2324 if (!secret_state
) {
2325 return NT_STATUS_NO_MEMORY
;
2327 secret_state
->policy
= policy_state
;
2329 if (strncmp("G$", r
->in
.name
.string
, 2) == 0) {
2330 name
= &r
->in
.name
.string
[2];
2331 secret_state
->sam_ldb
= talloc_reference(secret_state
, policy_state
->sam_ldb
);
2332 secret_state
->global
= True
;
2334 if (strlen(name
) < 1) {
2335 return NT_STATUS_INVALID_PARAMETER
;
2338 /* search for the secret record */
2339 ret
= gendb_search(secret_state
->sam_ldb
,
2340 mem_ctx
, policy_state
->system_dn
, &msgs
, attrs
,
2341 "(&(cn=%s Secret)(objectclass=secret))",
2342 ldb_binary_encode_string(mem_ctx
, name
));
2344 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2348 DEBUG(0,("Found %d records matching DN %s\n", ret
,
2349 ldb_dn_linearize(mem_ctx
, policy_state
->system_dn
)));
2350 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
2354 secret_state
->sam_ldb
= talloc_reference(secret_state
, secrets_db_connect(mem_ctx
));
2356 secret_state
->global
= False
;
2357 name
= r
->in
.name
.string
;
2358 if (strlen(name
) < 1) {
2359 return NT_STATUS_INVALID_PARAMETER
;
2362 /* search for the secret record */
2363 ret
= gendb_search(secret_state
->sam_ldb
, mem_ctx
,
2364 ldb_dn_explode(mem_ctx
, "cn=LSA Secrets"),
2366 "(&(cn=%s)(objectclass=secret))",
2367 ldb_binary_encode_string(mem_ctx
, name
));
2369 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2373 DEBUG(0,("Found %d records matching DN %s\n", ret
,
2374 ldb_dn_linearize(mem_ctx
, policy_state
->system_dn
)));
2375 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
2379 secret_state
->secret_dn
= talloc_reference(secret_state
, msgs
[0]->dn
);
2381 handle
= dcesrv_handle_new(dce_call
->context
, LSA_HANDLE_SECRET
);
2383 return NT_STATUS_NO_MEMORY
;
2386 handle
->data
= talloc_steal(handle
, secret_state
);
2388 secret_state
->access_mask
= r
->in
.access_mask
;
2389 secret_state
->policy
= talloc_reference(secret_state
, policy_state
);
2391 *r
->out
.sec_handle
= handle
->wire_handle
;
2393 return NT_STATUS_OK
;
2400 static NTSTATUS
lsa_SetSecret(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
2401 struct lsa_SetSecret
*r
)
2404 struct dcesrv_handle
*h
;
2405 struct lsa_secret_state
*secret_state
;
2406 struct ldb_message
*msg
;
2407 DATA_BLOB session_key
;
2408 DATA_BLOB crypt_secret
, secret
;
2411 NTSTATUS status
= NT_STATUS_OK
;
2413 struct timeval now
= timeval_current();
2414 NTTIME nt_now
= timeval_to_nttime(&now
);
2416 DCESRV_PULL_HANDLE(h
, r
->in
.sec_handle
, LSA_HANDLE_SECRET
);
2418 secret_state
= h
->data
;
2420 msg
= ldb_msg_new(mem_ctx
);
2422 return NT_STATUS_NO_MEMORY
;
2425 msg
->dn
= talloc_reference(mem_ctx
, secret_state
->secret_dn
);
2427 return NT_STATUS_NO_MEMORY
;
2429 status
= dcesrv_fetch_session_key(dce_call
->conn
, &session_key
);
2430 if (!NT_STATUS_IS_OK(status
)) {
2434 if (r
->in
.old_val
) {
2436 crypt_secret
.data
= r
->in
.old_val
->data
;
2437 crypt_secret
.length
= r
->in
.old_val
->size
;
2439 status
= sess_decrypt_blob(mem_ctx
, &crypt_secret
, &session_key
, &secret
);
2440 if (!NT_STATUS_IS_OK(status
)) {
2444 val
.data
= secret
.data
;
2445 val
.length
= secret
.length
;
2448 if (samdb_msg_add_value(secret_state
->sam_ldb
,
2449 mem_ctx
, msg
, "priorValue", &val
) != 0) {
2450 return NT_STATUS_NO_MEMORY
;
2453 /* set old value mtime */
2454 if (samdb_msg_add_uint64(secret_state
->sam_ldb
,
2455 mem_ctx
, msg
, "priorSetTime", nt_now
) != 0) {
2456 return NT_STATUS_NO_MEMORY
;
2459 if (!r
->in
.new_val
) {
2460 /* This behaviour varies depending of if this is a local, or a global secret... */
2461 if (secret_state
->global
) {
2462 /* set old value mtime */
2463 if (samdb_msg_add_uint64(secret_state
->sam_ldb
,
2464 mem_ctx
, msg
, "lastSetTime", nt_now
) != 0) {
2465 return NT_STATUS_NO_MEMORY
;
2468 if (samdb_msg_add_delete(secret_state
->sam_ldb
,
2469 mem_ctx
, msg
, "currentValue")) {
2470 return NT_STATUS_NO_MEMORY
;
2472 if (samdb_msg_add_delete(secret_state
->sam_ldb
,
2473 mem_ctx
, msg
, "lastSetTime")) {
2474 return NT_STATUS_NO_MEMORY
;
2480 if (r
->in
.new_val
) {
2482 crypt_secret
.data
= r
->in
.new_val
->data
;
2483 crypt_secret
.length
= r
->in
.new_val
->size
;
2485 status
= sess_decrypt_blob(mem_ctx
, &crypt_secret
, &session_key
, &secret
);
2486 if (!NT_STATUS_IS_OK(status
)) {
2490 val
.data
= secret
.data
;
2491 val
.length
= secret
.length
;
2494 if (samdb_msg_add_value(secret_state
->sam_ldb
,
2495 mem_ctx
, msg
, "currentValue", &val
) != 0) {
2496 return NT_STATUS_NO_MEMORY
;
2499 /* set new value mtime */
2500 if (samdb_msg_add_uint64(secret_state
->sam_ldb
,
2501 mem_ctx
, msg
, "lastSetTime", nt_now
) != 0) {
2502 return NT_STATUS_NO_MEMORY
;
2505 /* If the old value is not set, then migrate the
2506 * current value to the old value */
2507 if (!r
->in
.old_val
) {
2508 const struct ldb_val
*new_val
;
2509 NTTIME last_set_time
;
2510 struct ldb_message
**res
;
2511 const char *attrs
[] = {
2517 /* search for the secret record */
2518 ret
= gendb_search_dn(secret_state
->sam_ldb
,mem_ctx
,
2519 secret_state
->secret_dn
, &res
, attrs
);
2521 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2525 DEBUG(0,("Found %d records matching dn=%s\n", ret
,
2526 ldb_dn_linearize(mem_ctx
, secret_state
->secret_dn
)));
2527 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
2530 new_val
= ldb_msg_find_ldb_val(res
[0], "currentValue");
2531 last_set_time
= ldb_msg_find_attr_as_uint64(res
[0], "lastSetTime", 0);
2535 if (samdb_msg_add_value(secret_state
->sam_ldb
,
2536 mem_ctx
, msg
, "priorValue",
2538 return NT_STATUS_NO_MEMORY
;
2542 /* set new value mtime */
2543 if (ldb_msg_find_ldb_val(res
[0], "lastSetTime")) {
2544 if (samdb_msg_add_uint64(secret_state
->sam_ldb
,
2545 mem_ctx
, msg
, "priorSetTime", last_set_time
) != 0) {
2546 return NT_STATUS_NO_MEMORY
;
2552 /* modify the samdb record */
2553 ret
= samdb_replace(secret_state
->sam_ldb
, mem_ctx
, msg
);
2555 /* we really need samdb.c to return NTSTATUS */
2556 return NT_STATUS_UNSUCCESSFUL
;
2559 return NT_STATUS_OK
;
2566 static NTSTATUS
lsa_QuerySecret(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
2567 struct lsa_QuerySecret
*r
)
2569 struct dcesrv_handle
*h
;
2570 struct lsa_secret_state
*secret_state
;
2571 struct ldb_message
*msg
;
2572 DATA_BLOB session_key
;
2573 DATA_BLOB crypt_secret
, secret
;
2575 struct ldb_message
**res
;
2576 const char *attrs
[] = {
2586 DCESRV_PULL_HANDLE(h
, r
->in
.sec_handle
, LSA_HANDLE_SECRET
);
2588 secret_state
= h
->data
;
2590 /* pull all the user attributes */
2591 ret
= gendb_search_dn(secret_state
->sam_ldb
, mem_ctx
,
2592 secret_state
->secret_dn
, &res
, attrs
);
2594 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
2598 nt_status
= dcesrv_fetch_session_key(dce_call
->conn
, &session_key
);
2599 if (!NT_STATUS_IS_OK(nt_status
)) {
2603 if (r
->in
.old_val
) {
2604 const struct ldb_val
*prior_val
;
2605 r
->out
.old_val
= talloc_zero(mem_ctx
, struct lsa_DATA_BUF_PTR
);
2606 if (!r
->out
.old_val
) {
2607 return NT_STATUS_NO_MEMORY
;
2610 prior_val
= ldb_msg_find_ldb_val(res
[0], "priorValue");
2612 if (prior_val
&& prior_val
->length
) {
2613 secret
.data
= prior_val
->data
;
2614 secret
.length
= prior_val
->length
;
2616 crypt_secret
= sess_encrypt_blob(mem_ctx
, &secret
, &session_key
);
2617 if (!crypt_secret
.length
) {
2618 return NT_STATUS_NO_MEMORY
;
2620 r
->out
.old_val
->buf
= talloc(mem_ctx
, struct lsa_DATA_BUF
);
2621 if (!r
->out
.old_val
->buf
) {
2622 return NT_STATUS_NO_MEMORY
;
2624 r
->out
.old_val
->buf
->size
= crypt_secret
.length
;
2625 r
->out
.old_val
->buf
->length
= crypt_secret
.length
;
2626 r
->out
.old_val
->buf
->data
= crypt_secret
.data
;
2630 if (r
->in
.old_mtime
) {
2631 r
->out
.old_mtime
= talloc(mem_ctx
, NTTIME
);
2632 if (!r
->out
.old_mtime
) {
2633 return NT_STATUS_NO_MEMORY
;
2635 *r
->out
.old_mtime
= ldb_msg_find_attr_as_uint64(res
[0], "priorSetTime", 0);
2638 if (r
->in
.new_val
) {
2639 const struct ldb_val
*new_val
;
2640 r
->out
.new_val
= talloc_zero(mem_ctx
, struct lsa_DATA_BUF_PTR
);
2641 if (!r
->out
.new_val
) {
2642 return NT_STATUS_NO_MEMORY
;
2646 new_val
= ldb_msg_find_ldb_val(res
[0], "currentValue");
2648 if (new_val
&& new_val
->length
) {
2649 secret
.data
= new_val
->data
;
2650 secret
.length
= new_val
->length
;
2652 crypt_secret
= sess_encrypt_blob(mem_ctx
, &secret
, &session_key
);
2653 if (!crypt_secret
.length
) {
2654 return NT_STATUS_NO_MEMORY
;
2656 r
->out
.new_val
->buf
= talloc(mem_ctx
, struct lsa_DATA_BUF
);
2657 if (!r
->out
.new_val
->buf
) {
2658 return NT_STATUS_NO_MEMORY
;
2660 r
->out
.new_val
->buf
->length
= crypt_secret
.length
;
2661 r
->out
.new_val
->buf
->size
= crypt_secret
.length
;
2662 r
->out
.new_val
->buf
->data
= crypt_secret
.data
;
2666 if (r
->in
.new_mtime
) {
2667 r
->out
.new_mtime
= talloc(mem_ctx
, NTTIME
);
2668 if (!r
->out
.new_mtime
) {
2669 return NT_STATUS_NO_MEMORY
;
2671 *r
->out
.new_mtime
= ldb_msg_find_attr_as_uint64(res
[0], "lastSetTime", 0);
2674 return NT_STATUS_OK
;
2681 static NTSTATUS
lsa_LookupPrivValue(struct dcesrv_call_state
*dce_call
,
2682 TALLOC_CTX
*mem_ctx
,
2683 struct lsa_LookupPrivValue
*r
)
2685 struct dcesrv_handle
*h
;
2686 struct lsa_policy_state
*state
;
2689 DCESRV_PULL_HANDLE(h
, r
->in
.handle
, LSA_HANDLE_POLICY
);
2693 id
= sec_privilege_id(r
->in
.name
->string
);
2695 return NT_STATUS_NO_SUCH_PRIVILEGE
;
2698 r
->out
.luid
->low
= id
;
2699 r
->out
.luid
->high
= 0;
2701 return NT_STATUS_OK
;
2708 static NTSTATUS
lsa_LookupPrivName(struct dcesrv_call_state
*dce_call
,
2709 TALLOC_CTX
*mem_ctx
,
2710 struct lsa_LookupPrivName
*r
)
2712 struct dcesrv_handle
*h
;
2713 struct lsa_policy_state
*state
;
2714 const char *privname
;
2716 DCESRV_PULL_HANDLE(h
, r
->in
.handle
, LSA_HANDLE_POLICY
);
2720 if (r
->in
.luid
->high
!= 0) {
2721 return NT_STATUS_NO_SUCH_PRIVILEGE
;
2724 privname
= sec_privilege_name(r
->in
.luid
->low
);
2725 if (privname
== NULL
) {
2726 return NT_STATUS_NO_SUCH_PRIVILEGE
;
2729 r
->out
.name
= talloc(mem_ctx
, struct lsa_StringLarge
);
2730 if (r
->out
.name
== NULL
) {
2731 return NT_STATUS_NO_MEMORY
;
2733 r
->out
.name
->string
= privname
;
2735 return NT_STATUS_OK
;
2740 lsa_LookupPrivDisplayName
2742 static NTSTATUS
lsa_LookupPrivDisplayName(struct dcesrv_call_state
*dce_call
,
2743 TALLOC_CTX
*mem_ctx
,
2744 struct lsa_LookupPrivDisplayName
*r
)
2746 struct dcesrv_handle
*h
;
2747 struct lsa_policy_state
*state
;
2750 DCESRV_PULL_HANDLE(h
, r
->in
.handle
, LSA_HANDLE_POLICY
);
2754 id
= sec_privilege_id(r
->in
.name
->string
);
2756 return NT_STATUS_NO_SUCH_PRIVILEGE
;
2759 r
->out
.disp_name
= talloc(mem_ctx
, struct lsa_StringLarge
);
2760 if (r
->out
.disp_name
== NULL
) {
2761 return NT_STATUS_NO_MEMORY
;
2764 r
->out
.disp_name
->string
= sec_privilege_display_name(id
, r
->in
.language_id
);
2765 if (r
->out
.disp_name
->string
== NULL
) {
2766 return NT_STATUS_INTERNAL_ERROR
;
2769 return NT_STATUS_OK
;
2776 static NTSTATUS
lsa_DeleteObject(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
2777 struct lsa_DeleteObject
*r
)
2779 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
2784 lsa_EnumAccountsWithUserRight
2786 static NTSTATUS
lsa_EnumAccountsWithUserRight(struct dcesrv_call_state
*dce_call
,
2787 TALLOC_CTX
*mem_ctx
,
2788 struct lsa_EnumAccountsWithUserRight
*r
)
2790 struct dcesrv_handle
*h
;
2791 struct lsa_policy_state
*state
;
2793 struct ldb_message
**res
;
2794 const char * const attrs
[] = { "objectSid", NULL
};
2795 const char *privname
;
2797 DCESRV_PULL_HANDLE(h
, r
->in
.handle
, LSA_HANDLE_POLICY
);
2801 if (r
->in
.name
== NULL
) {
2802 return NT_STATUS_NO_SUCH_PRIVILEGE
;
2805 privname
= r
->in
.name
->string
;
2806 if (sec_privilege_id(privname
) == -1) {
2807 return NT_STATUS_NO_SUCH_PRIVILEGE
;
2810 ret
= gendb_search(state
->sam_ldb
, mem_ctx
, NULL
, &res
, attrs
,
2811 "privilege=%s", privname
);
2813 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
2816 return NT_STATUS_NO_MORE_ENTRIES
;
2819 r
->out
.sids
->sids
= talloc_array(r
->out
.sids
, struct lsa_SidPtr
, ret
);
2820 if (r
->out
.sids
->sids
== NULL
) {
2821 return NT_STATUS_NO_MEMORY
;
2823 for (i
=0;i
<ret
;i
++) {
2824 r
->out
.sids
->sids
[i
].sid
= samdb_result_dom_sid(r
->out
.sids
->sids
,
2825 res
[i
], "objectSid");
2826 NT_STATUS_HAVE_NO_MEMORY(r
->out
.sids
->sids
[i
].sid
);
2828 r
->out
.sids
->num_sids
= ret
;
2830 return NT_STATUS_OK
;
2835 lsa_AddAccountRights
2837 static NTSTATUS
lsa_AddAccountRights(struct dcesrv_call_state
*dce_call
,
2838 TALLOC_CTX
*mem_ctx
,
2839 struct lsa_AddAccountRights
*r
)
2841 struct dcesrv_handle
*h
;
2842 struct lsa_policy_state
*state
;
2844 DCESRV_PULL_HANDLE(h
, r
->in
.handle
, LSA_HANDLE_POLICY
);
2848 return lsa_AddRemoveAccountRights(dce_call
, mem_ctx
, state
,
2850 r
->in
.sid
, r
->in
.rights
);
2855 lsa_RemoveAccountRights
2857 static NTSTATUS
lsa_RemoveAccountRights(struct dcesrv_call_state
*dce_call
,
2858 TALLOC_CTX
*mem_ctx
,
2859 struct lsa_RemoveAccountRights
*r
)
2861 struct dcesrv_handle
*h
;
2862 struct lsa_policy_state
*state
;
2864 DCESRV_PULL_HANDLE(h
, r
->in
.handle
, LSA_HANDLE_POLICY
);
2868 return lsa_AddRemoveAccountRights(dce_call
, mem_ctx
, state
,
2869 LDB_FLAG_MOD_DELETE
,
2870 r
->in
.sid
, r
->in
.rights
);
2875 lsa_StorePrivateData
2877 static NTSTATUS
lsa_StorePrivateData(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
2878 struct lsa_StorePrivateData
*r
)
2880 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
2885 lsa_RetrievePrivateData
2887 static NTSTATUS
lsa_RetrievePrivateData(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
2888 struct lsa_RetrievePrivateData
*r
)
2890 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
2897 static NTSTATUS
lsa_GetUserName(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
2898 struct lsa_GetUserName
*r
)
2900 NTSTATUS status
= NT_STATUS_OK
;
2901 const char *account_name
;
2902 const char *authority_name
;
2903 struct lsa_String
*_account_name
;
2904 struct lsa_StringPointer
*_authority_name
= NULL
;
2906 /* this is what w2k3 does */
2907 r
->out
.account_name
= r
->in
.account_name
;
2908 r
->out
.authority_name
= r
->in
.authority_name
;
2910 if (r
->in
.account_name
&& r
->in
.account_name
->string
) {
2911 return NT_STATUS_INVALID_PARAMETER
;
2914 if (r
->in
.authority_name
&&
2915 r
->in
.authority_name
->string
&&
2916 r
->in
.authority_name
->string
->string
) {
2917 return NT_STATUS_INVALID_PARAMETER
;
2920 account_name
= talloc_reference(mem_ctx
, dce_call
->conn
->auth_state
.session_info
->server_info
->account_name
);
2921 authority_name
= talloc_reference(mem_ctx
, dce_call
->conn
->auth_state
.session_info
->server_info
->domain_name
);
2923 _account_name
= talloc(mem_ctx
, struct lsa_String
);
2924 NT_STATUS_HAVE_NO_MEMORY(_account_name
);
2925 _account_name
->string
= account_name
;
2927 if (r
->in
.authority_name
) {
2928 _authority_name
= talloc(mem_ctx
, struct lsa_StringPointer
);
2929 NT_STATUS_HAVE_NO_MEMORY(_authority_name
);
2930 _authority_name
->string
= talloc(mem_ctx
, struct lsa_String
);
2931 NT_STATUS_HAVE_NO_MEMORY(_authority_name
->string
);
2932 _authority_name
->string
->string
= authority_name
;
2935 r
->out
.account_name
= _account_name
;
2936 r
->out
.authority_name
= _authority_name
;
2944 static NTSTATUS
lsa_SetInfoPolicy2(struct dcesrv_call_state
*dce_call
,
2945 TALLOC_CTX
*mem_ctx
,
2946 struct lsa_SetInfoPolicy2
*r
)
2948 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
2952 lsa_QueryDomainInformationPolicy
2954 static NTSTATUS
lsa_QueryDomainInformationPolicy(struct dcesrv_call_state
*dce_call
,
2955 TALLOC_CTX
*mem_ctx
,
2956 struct lsa_QueryDomainInformationPolicy
*r
)
2958 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
2962 lsa_SetDomInfoPolicy
2964 static NTSTATUS
lsa_SetDomainInformationPolicy(struct dcesrv_call_state
*dce_call
,
2965 TALLOC_CTX
*mem_ctx
,
2966 struct lsa_SetDomainInformationPolicy
*r
)
2968 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
2974 static NTSTATUS
lsa_TestCall(struct dcesrv_call_state
*dce_call
,
2975 TALLOC_CTX
*mem_ctx
,
2976 struct lsa_TestCall
*r
)
2978 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
2982 lookup a SID for 1 name
2984 static NTSTATUS
lsa_lookup_name(struct lsa_policy_state
*state
, TALLOC_CTX
*mem_ctx
,
2985 const char *name
, struct dom_sid
**sid
, uint32_t *atype
)
2988 struct ldb_message
**res
;
2989 const char * const attrs
[] = { "objectSid", "sAMAccountType", NULL
};
2992 p
= strchr_m(name
, '\\');
2994 /* TODO: properly parse the domain prefix here, and use it to
2999 ret
= gendb_search(state
->sam_ldb
, mem_ctx
, NULL
, &res
, attrs
, "sAMAccountName=%s", ldb_binary_encode_string(mem_ctx
, name
));
3001 *sid
= samdb_result_dom_sid(mem_ctx
, res
[0], "objectSid");
3003 return NT_STATUS_INVALID_SID
;
3006 *atype
= samdb_result_uint(res
[0], "sAMAccountType", 0);
3008 return NT_STATUS_OK
;
3011 /* need to add a call into sidmap to check for a allocated sid */
3013 return NT_STATUS_INVALID_SID
;
3020 static NTSTATUS
lsa_LookupNames3(struct dcesrv_call_state
*dce_call
,
3021 TALLOC_CTX
*mem_ctx
,
3022 struct lsa_LookupNames3
*r
)
3024 struct lsa_policy_state
*policy_state
;
3025 struct dcesrv_handle
*policy_handle
;
3027 NTSTATUS status
= NT_STATUS_OK
;
3029 DCESRV_PULL_HANDLE(policy_handle
, r
->in
.handle
, LSA_HANDLE_POLICY
);
3031 policy_state
= policy_handle
->data
;
3033 r
->out
.domains
= NULL
;
3035 r
->out
.domains
= talloc_zero(mem_ctx
, struct lsa_RefDomainList
);
3036 if (r
->out
.domains
== NULL
) {
3037 return NT_STATUS_NO_MEMORY
;
3040 r
->out
.sids
= talloc_zero(mem_ctx
, struct lsa_TransSidArray3
);
3041 if (r
->out
.sids
== NULL
) {
3042 return NT_STATUS_NO_MEMORY
;
3047 r
->out
.sids
->sids
= talloc_array(r
->out
.sids
, struct lsa_TranslatedSid3
,
3049 if (r
->out
.sids
->sids
== NULL
) {
3050 return NT_STATUS_NO_MEMORY
;
3053 for (i
=0;i
<r
->in
.num_names
;i
++) {
3054 const char *name
= r
->in
.names
[i
].string
;
3055 struct dom_sid
*sid
;
3056 uint32_t atype
, rtype
, sid_index
;
3059 r
->out
.sids
->count
++;
3062 r
->out
.sids
->sids
[i
].sid_type
= SID_NAME_UNKNOWN
;
3063 r
->out
.sids
->sids
[i
].sid
= NULL
;
3064 r
->out
.sids
->sids
[i
].sid_index
= 0xFFFFFFFF;
3065 r
->out
.sids
->sids
[i
].unknown
= 0;
3067 status2
= lsa_lookup_name(policy_state
, mem_ctx
, name
, &sid
, &atype
);
3068 if (!NT_STATUS_IS_OK(status2
) || sid
->num_auths
== 0) {
3069 status
= STATUS_SOME_UNMAPPED
;
3073 rtype
= samdb_atype_map(atype
);
3074 if (rtype
== SID_NAME_UNKNOWN
) {
3075 status
= STATUS_SOME_UNMAPPED
;
3079 status2
= lsa_authority_list(policy_state
, mem_ctx
, sid
, r
->out
.domains
, &sid_index
);
3080 if (!NT_STATUS_IS_OK(status2
)) {
3084 r
->out
.sids
->sids
[i
].sid_type
= rtype
;
3085 r
->out
.sids
->sids
[i
].sid
= sid
;
3086 r
->out
.sids
->sids
[i
].sid_index
= sid_index
;
3087 r
->out
.sids
->sids
[i
].unknown
= 0;
3096 Identical to LookupNames3, but doesn't take a policy handle
3099 static NTSTATUS
lsa_LookupNames4(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
3100 struct lsa_LookupNames4
*r
)
3102 struct lsa_LookupNames3 r2
;
3103 struct lsa_OpenPolicy2 pol
;
3105 struct dcesrv_handle
*h
;
3107 /* No policy handle on the wire, so make one up here */
3108 r2
.in
.handle
= talloc(mem_ctx
, struct policy_handle
);
3109 if (!r2
.in
.handle
) {
3110 return NT_STATUS_NO_MEMORY
;
3113 pol
.out
.handle
= r2
.in
.handle
;
3114 pol
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3116 pol
.in
.system_name
= NULL
;
3117 status
= lsa_OpenPolicy2(dce_call
, mem_ctx
, &pol
);
3118 if (!NT_STATUS_IS_OK(status
)) {
3122 /* ensure this handle goes away at the end of this call */
3123 DCESRV_PULL_HANDLE(h
, r2
.in
.handle
, LSA_HANDLE_POLICY
);
3124 talloc_steal(mem_ctx
, h
);
3126 r2
.in
.num_names
= r
->in
.num_names
;
3127 r2
.in
.names
= r
->in
.names
;
3128 r2
.in
.sids
= r
->in
.sids
;
3129 r2
.in
.count
= r
->in
.count
;
3130 r2
.in
.unknown1
= r
->in
.unknown1
;
3131 r2
.in
.unknown2
= r
->in
.unknown2
;
3132 r2
.out
.domains
= r
->out
.domains
;
3133 r2
.out
.sids
= r
->out
.sids
;
3134 r2
.out
.count
= r
->out
.count
;
3136 status
= lsa_LookupNames3(dce_call
, mem_ctx
, &r2
);
3137 if (dce_call
->fault_code
!= 0) {
3141 r
->out
.domains
= r2
.out
.domains
;
3142 r
->out
.sids
= r2
.out
.sids
;
3143 r
->out
.count
= r2
.out
.count
;
3150 static NTSTATUS
lsa_LookupNames2(struct dcesrv_call_state
*dce_call
,
3151 TALLOC_CTX
*mem_ctx
,
3152 struct lsa_LookupNames2
*r
)
3154 struct lsa_policy_state
*state
;
3155 struct dcesrv_handle
*h
;
3157 NTSTATUS status
= NT_STATUS_OK
;
3159 r
->out
.domains
= NULL
;
3161 DCESRV_PULL_HANDLE(h
, r
->in
.handle
, LSA_HANDLE_POLICY
);
3165 r
->out
.domains
= talloc_zero(mem_ctx
, struct lsa_RefDomainList
);
3166 if (r
->out
.domains
== NULL
) {
3167 return NT_STATUS_NO_MEMORY
;
3170 r
->out
.sids
= talloc_zero(mem_ctx
, struct lsa_TransSidArray2
);
3171 if (r
->out
.sids
== NULL
) {
3172 return NT_STATUS_NO_MEMORY
;
3177 r
->out
.sids
->sids
= talloc_array(r
->out
.sids
, struct lsa_TranslatedSid2
,
3179 if (r
->out
.sids
->sids
== NULL
) {
3180 return NT_STATUS_NO_MEMORY
;
3183 for (i
=0;i
<r
->in
.num_names
;i
++) {
3184 const char *name
= r
->in
.names
[i
].string
;
3185 struct dom_sid
*sid
;
3186 uint32_t atype
, rtype
, sid_index
;
3189 r
->out
.sids
->count
++;
3192 r
->out
.sids
->sids
[i
].sid_type
= SID_NAME_UNKNOWN
;
3193 r
->out
.sids
->sids
[i
].rid
= 0xFFFFFFFF;
3194 r
->out
.sids
->sids
[i
].sid_index
= 0xFFFFFFFF;
3195 r
->out
.sids
->sids
[i
].unknown
= 0;
3197 status2
= lsa_lookup_name(state
, mem_ctx
, name
, &sid
, &atype
);
3198 if (!NT_STATUS_IS_OK(status2
) || sid
->num_auths
== 0) {
3199 status
= STATUS_SOME_UNMAPPED
;
3203 rtype
= samdb_atype_map(atype
);
3204 if (rtype
== SID_NAME_UNKNOWN
) {
3205 status
= STATUS_SOME_UNMAPPED
;
3209 status2
= lsa_authority_list(state
, mem_ctx
, sid
, r
->out
.domains
, &sid_index
);
3210 if (!NT_STATUS_IS_OK(status2
)) {
3214 r
->out
.sids
->sids
[i
].sid_type
= rtype
;
3215 r
->out
.sids
->sids
[i
].rid
= sid
->sub_auths
[sid
->num_auths
-1];
3216 r
->out
.sids
->sids
[i
].sid_index
= sid_index
;
3217 r
->out
.sids
->sids
[i
].unknown
= 0;
3226 static NTSTATUS
lsa_LookupNames(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
3227 struct lsa_LookupNames
*r
)
3229 struct lsa_LookupNames2 r2
;
3233 r2
.in
.handle
= r
->in
.handle
;
3234 r2
.in
.num_names
= r
->in
.num_names
;
3235 r2
.in
.names
= r
->in
.names
;
3237 r2
.in
.level
= r
->in
.level
;
3238 r2
.in
.count
= r
->in
.count
;
3241 r2
.out
.count
= r
->out
.count
;
3243 status
= lsa_LookupNames2(dce_call
, mem_ctx
, &r2
);
3244 if (dce_call
->fault_code
!= 0) {
3248 r
->out
.domains
= r2
.out
.domains
;
3249 r
->out
.sids
= talloc(mem_ctx
, struct lsa_TransSidArray
);
3250 if (r
->out
.sids
== NULL
) {
3251 return NT_STATUS_NO_MEMORY
;
3253 r
->out
.sids
->count
= r2
.out
.sids
->count
;
3254 r
->out
.sids
->sids
= talloc_array(r
->out
.sids
, struct lsa_TranslatedSid
,
3255 r
->out
.sids
->count
);
3256 if (r
->out
.sids
->sids
== NULL
) {
3257 return NT_STATUS_NO_MEMORY
;
3259 for (i
=0;i
<r
->out
.sids
->count
;i
++) {
3260 r
->out
.sids
->sids
[i
].sid_type
= r2
.out
.sids
->sids
[i
].sid_type
;
3261 r
->out
.sids
->sids
[i
].rid
= r2
.out
.sids
->sids
[i
].rid
;
3262 r
->out
.sids
->sids
[i
].sid_index
= r2
.out
.sids
->sids
[i
].sid_index
;
3271 static NTSTATUS
lsa_CREDRWRITE(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
3272 struct lsa_CREDRWRITE
*r
)
3274 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
3281 static NTSTATUS
lsa_CREDRREAD(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
3282 struct lsa_CREDRREAD
*r
)
3284 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
3291 static NTSTATUS
lsa_CREDRENUMERATE(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
3292 struct lsa_CREDRENUMERATE
*r
)
3294 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
3299 lsa_CREDRWRITEDOMAINCREDENTIALS
3301 static NTSTATUS
lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
3302 struct lsa_CREDRWRITEDOMAINCREDENTIALS
*r
)
3304 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
3309 lsa_CREDRREADDOMAINCREDENTIALS
3311 static NTSTATUS
lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
3312 struct lsa_CREDRREADDOMAINCREDENTIALS
*r
)
3314 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
3321 static NTSTATUS
lsa_CREDRDELETE(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
3322 struct lsa_CREDRDELETE
*r
)
3324 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
3329 lsa_CREDRGETTARGETINFO
3331 static NTSTATUS
lsa_CREDRGETTARGETINFO(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
3332 struct lsa_CREDRGETTARGETINFO
*r
)
3334 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
3339 lsa_CREDRPROFILELOADED
3341 static NTSTATUS
lsa_CREDRPROFILELOADED(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
3342 struct lsa_CREDRPROFILELOADED
*r
)
3344 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
3349 lsa_CREDRGETSESSIONTYPES
3351 static NTSTATUS
lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
3352 struct lsa_CREDRGETSESSIONTYPES
*r
)
3354 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
3359 lsa_LSARREGISTERAUDITEVENT
3361 static NTSTATUS
lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
3362 struct lsa_LSARREGISTERAUDITEVENT
*r
)
3364 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
3369 lsa_LSARGENAUDITEVENT
3371 static NTSTATUS
lsa_LSARGENAUDITEVENT(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
3372 struct lsa_LSARGENAUDITEVENT
*r
)
3374 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
3379 lsa_LSARUNREGISTERAUDITEVENT
3381 static NTSTATUS
lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
3382 struct lsa_LSARUNREGISTERAUDITEVENT
*r
)
3384 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
3389 lsa_LSARQUERYFORESTTRUSTINFORMATION
3391 static NTSTATUS
lsa_LSARQUERYFORESTTRUSTINFORMATION(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
3392 struct lsa_LSARQUERYFORESTTRUSTINFORMATION
*r
)
3394 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
3399 lsa_LSARSETFORESTTRUSTINFORMATION
3401 static NTSTATUS
lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
3402 struct lsa_LSARSETFORESTTRUSTINFORMATION
*r
)
3404 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
3411 static NTSTATUS
lsa_CREDRRENAME(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
3412 struct lsa_CREDRRENAME
*r
)
3414 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
3420 lsa_LSAROPENPOLICYSCE
3422 static NTSTATUS
lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
3423 struct lsa_LSAROPENPOLICYSCE
*r
)
3425 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
3430 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
3432 static NTSTATUS
lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
3433 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE
*r
)
3435 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
3440 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
3442 static NTSTATUS
lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
3443 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
*r
)
3445 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
3450 lsa_LSARADTREPORTSECURITYEVENT
3452 static NTSTATUS
lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
3453 struct lsa_LSARADTREPORTSECURITYEVENT
*r
)
3455 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
3459 /* include the generated boilerplate */
3460 #include "librpc/gen_ndr/ndr_lsa_s.c"
3464 /*****************************************
3465 NOTE! The remaining calls below were
3466 removed in w2k3, so the DCESRV_FAULT()
3467 replies are the correct implementation. Do
3468 not try and fill these in with anything else
3469 ******************************************/
3472 dssetup_DsRoleDnsNameToFlatName
3474 static WERROR
dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
3475 struct dssetup_DsRoleDnsNameToFlatName
*r
)
3477 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
3482 dssetup_DsRoleDcAsDc
3484 static WERROR
dssetup_DsRoleDcAsDc(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
3485 struct dssetup_DsRoleDcAsDc
*r
)
3487 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
3492 dssetup_DsRoleDcAsReplica
3494 static WERROR
dssetup_DsRoleDcAsReplica(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
3495 struct dssetup_DsRoleDcAsReplica
*r
)
3497 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
3502 dssetup_DsRoleDemoteDc
3504 static WERROR
dssetup_DsRoleDemoteDc(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
3505 struct dssetup_DsRoleDemoteDc
*r
)
3507 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
3512 dssetup_DsRoleGetDcOperationProgress
3514 static WERROR
dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
3515 struct dssetup_DsRoleGetDcOperationProgress
*r
)
3517 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
3522 dssetup_DsRoleGetDcOperationResults
3524 static WERROR
dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
3525 struct dssetup_DsRoleGetDcOperationResults
*r
)
3527 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
3532 dssetup_DsRoleCancel
3534 static WERROR
dssetup_DsRoleCancel(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
3535 struct dssetup_DsRoleCancel
*r
)
3537 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
3542 dssetup_DsRoleServerSaveStateForUpgrade
3544 static WERROR
dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
3545 struct dssetup_DsRoleServerSaveStateForUpgrade
*r
)
3547 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
3552 dssetup_DsRoleUpgradeDownlevelServer
3554 static WERROR
dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
3555 struct dssetup_DsRoleUpgradeDownlevelServer
*r
)
3557 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
3562 dssetup_DsRoleAbortDownlevelServerUpgrade
3564 static WERROR
dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
3565 struct dssetup_DsRoleAbortDownlevelServerUpgrade
*r
)
3567 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
3571 /* include the generated boilerplate */
3572 #include "librpc/gen_ndr/ndr_dssetup_s.c"
3574 NTSTATUS
dcerpc_server_lsa_init(void)
3578 ret
= dcerpc_server_dssetup_init();
3579 if (!NT_STATUS_IS_OK(ret
)) {
3582 ret
= dcerpc_server_lsarpc_init();
3583 if (!NT_STATUS_IS_OK(ret
)) {