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 "libds/common/flag_mapping.h"
30 enum lsa_SidType rtype
;
35 .rtype
= SID_NAME_WKN_GRP
,
38 .name
= "CREATOR OWNER",
39 .sid
= SID_CREATOR_OWNER
,
40 .rtype
= SID_NAME_WKN_GRP
,
43 .name
= "CREATOR GROUP",
44 .sid
= SID_CREATOR_GROUP
,
45 .rtype
= SID_NAME_WKN_GRP
,
48 .name
= "Owner Rights",
49 .sid
= SID_OWNER_RIGHTS
,
50 .rtype
= SID_NAME_WKN_GRP
,
53 .domain
= "NT AUTHORITY",
56 .rtype
= SID_NAME_WKN_GRP
,
59 .domain
= "NT AUTHORITY",
61 .sid
= SID_NT_NETWORK
,
62 .rtype
= SID_NAME_WKN_GRP
,
65 .domain
= "NT AUTHORITY",
68 .rtype
= SID_NAME_WKN_GRP
,
71 .domain
= "NT AUTHORITY",
72 .name
= "Interactive",
73 .sid
= SID_NT_INTERACTIVE
,
74 .rtype
= SID_NAME_WKN_GRP
,
77 .domain
= "NT AUTHORITY",
79 .sid
= SID_NT_SERVICE
,
80 .rtype
= SID_NAME_WKN_GRP
,
83 .domain
= "NT AUTHORITY",
84 .name
= "ANONYMOUS LOGON",
85 .sid
= SID_NT_ANONYMOUS
,
86 .rtype
= SID_NAME_WKN_GRP
,
89 .domain
= "NT AUTHORITY",
92 .rtype
= SID_NAME_WKN_GRP
,
95 .domain
= "NT AUTHORITY",
96 .name
= "ServerLogon",
97 .sid
= SID_NT_ENTERPRISE_DCS
,
98 .rtype
= SID_NAME_WKN_GRP
,
101 .domain
= "NT AUTHORITY",
104 .rtype
= SID_NAME_WKN_GRP
,
107 .domain
= "NT AUTHORITY",
108 .name
= "Authenticated Users",
109 .sid
= SID_NT_AUTHENTICATED_USERS
,
110 .rtype
= SID_NAME_WKN_GRP
,
113 .domain
= "NT AUTHORITY",
114 .name
= "Restricted",
115 .sid
= SID_NT_RESTRICTED
,
116 .rtype
= SID_NAME_WKN_GRP
,
119 .domain
= "NT AUTHORITY",
120 .name
= "Terminal Server User",
121 .sid
= SID_NT_TERMINAL_SERVER_USERS
,
122 .rtype
= SID_NAME_WKN_GRP
,
125 .domain
= "NT AUTHORITY",
126 .name
= "Remote Interactive Logon",
127 .sid
= SID_NT_REMOTE_INTERACTIVE
,
128 .rtype
= SID_NAME_WKN_GRP
,
131 .domain
= "NT AUTHORITY",
132 .name
= "This Organization",
133 .sid
= SID_NT_THIS_ORGANISATION
,
134 .rtype
= SID_NAME_WKN_GRP
,
137 .domain
= "NT AUTHORITY",
139 .sid
= SID_NT_SYSTEM
,
140 .rtype
= SID_NAME_WKN_GRP
,
143 .domain
= "NT AUTHORITY",
144 .name
= "Local Service",
145 .sid
= SID_NT_LOCAL_SERVICE
,
146 .rtype
= SID_NAME_WKN_GRP
,
149 .domain
= "NT AUTHORITY",
150 .name
= "Network Service",
151 .sid
= SID_NT_NETWORK_SERVICE
,
152 .rtype
= SID_NAME_WKN_GRP
,
155 .domain
= "NT AUTHORITY",
156 .name
= "Digest Authentication",
157 .sid
= SID_NT_DIGEST_AUTHENTICATION
,
158 .rtype
= SID_NAME_WKN_GRP
,
161 .domain
= "NT AUTHORITY",
162 .name
= "Enterprise Domain Controllers",
163 .sid
= SID_NT_ENTERPRISE_DCS
,
164 .rtype
= SID_NAME_WKN_GRP
,
167 .domain
= "NT AUTHORITY",
168 .name
= "NTLM Authentication",
169 .sid
= SID_NT_NTLM_AUTHENTICATION
,
170 .rtype
= SID_NAME_WKN_GRP
,
173 .domain
= "NT AUTHORITY",
174 .name
= "Other Organization",
175 .sid
= SID_NT_OTHER_ORGANISATION
,
176 .rtype
= SID_NAME_WKN_GRP
,
179 .domain
= "NT AUTHORITY",
180 .name
= "SChannel Authentication",
181 .sid
= SID_NT_SCHANNEL_AUTHENTICATION
,
182 .rtype
= SID_NAME_WKN_GRP
,
185 .domain
= "NT AUTHORITY",
188 .rtype
= SID_NAME_WKN_GRP
,
195 static NTSTATUS
lookup_well_known_names(TALLOC_CTX
*mem_ctx
, const char *domain
,
196 const char *name
, const char **authority_name
,
197 struct dom_sid
**sid
, enum lsa_SidType
*rtype
)
200 for (i
=0; well_known
[i
].sid
; i
++) {
202 if (strcasecmp_m(domain
, well_known
[i
].domain
) == 0
203 && strcasecmp_m(name
, well_known
[i
].name
) == 0) {
204 *authority_name
= well_known
[i
].domain
;
205 *sid
= dom_sid_parse_talloc(mem_ctx
, well_known
[i
].sid
);
206 *rtype
= well_known
[i
].rtype
;
210 if (strcasecmp_m(name
, well_known
[i
].name
) == 0) {
211 *authority_name
= well_known
[i
].domain
;
212 *sid
= dom_sid_parse_talloc(mem_ctx
, well_known
[i
].sid
);
213 *rtype
= well_known
[i
].rtype
;
218 return NT_STATUS_NOT_FOUND
;
221 static NTSTATUS
lookup_well_known_sids(TALLOC_CTX
*mem_ctx
,
222 const char *sid_str
, const char **authority_name
,
223 const char **name
, enum lsa_SidType
*rtype
)
226 for (i
=0; well_known
[i
].sid
; i
++) {
227 if (strcasecmp_m(sid_str
, well_known
[i
].sid
) == 0) {
228 *authority_name
= well_known
[i
].domain
;
229 *name
= well_known
[i
].name
;
230 *rtype
= well_known
[i
].rtype
;
234 return NT_STATUS_NOT_FOUND
;
238 lookup a SID for 1 name
240 static NTSTATUS
dcesrv_lsa_lookup_name(struct tevent_context
*ev_ctx
,
241 struct loadparm_context
*lp_ctx
,
242 struct lsa_policy_state
*state
, TALLOC_CTX
*mem_ctx
,
243 const char *name
, const char **authority_name
,
244 struct dom_sid
**sid
, enum lsa_SidType
*rtype
,
249 struct ldb_message
**res
;
250 const char * const attrs
[] = { "objectSid", "sAMAccountType", NULL
};
253 const char *username
;
254 struct ldb_dn
*domain_dn
;
255 struct dom_sid
*domain_sid
;
258 p
= strchr_m(name
, '\\');
260 domain
= talloc_strndup(mem_ctx
, name
, p
-name
);
262 return NT_STATUS_NO_MEMORY
;
265 } else if (strchr_m(name
, '@')) {
266 status
= crack_name_to_nt4_name(mem_ctx
, ev_ctx
, lp_ctx
, DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL
, name
, &domain
, &username
);
267 if (!NT_STATUS_IS_OK(status
)) {
268 DEBUG(3, ("Failed to crack name %s into an NT4 name: %s\n", name
, nt_errstr(status
)));
277 /* Look up table of well known names */
278 status
= lookup_well_known_names(mem_ctx
, NULL
, username
, authority_name
, sid
, rtype
);
279 if (NT_STATUS_IS_OK(status
)) {
280 dom_sid_split_rid(NULL
, *sid
, NULL
, rid
);
284 if (username
== NULL
) {
285 *authority_name
= NAME_BUILTIN
;
286 *sid
= dom_sid_parse_talloc(mem_ctx
, SID_BUILTIN
);
288 return NT_STATUS_NO_MEMORY
;
290 *rtype
= SID_NAME_DOMAIN
;
295 if (strcasecmp_m(username
, NAME_NT_AUTHORITY
) == 0) {
296 *authority_name
= NAME_NT_AUTHORITY
;
297 *sid
= dom_sid_parse_talloc(mem_ctx
, SID_NT_AUTHORITY
);
299 return NT_STATUS_NO_MEMORY
;
301 *rtype
= SID_NAME_DOMAIN
;
302 dom_sid_split_rid(NULL
, *sid
, NULL
, rid
);
305 if (strcasecmp_m(username
, NAME_BUILTIN
) == 0) {
306 *authority_name
= NAME_BUILTIN
;
307 *sid
= dom_sid_parse_talloc(mem_ctx
, SID_BUILTIN
);
309 return NT_STATUS_NO_MEMORY
;
311 *rtype
= SID_NAME_DOMAIN
;
315 if (strcasecmp_m(username
, state
->domain_dns
) == 0) {
316 *authority_name
= talloc_strdup(mem_ctx
,
318 if (*authority_name
== NULL
) {
319 return NT_STATUS_NO_MEMORY
;
321 *sid
= dom_sid_dup(mem_ctx
, state
->domain_sid
);
323 return NT_STATUS_NO_MEMORY
;
325 *rtype
= SID_NAME_DOMAIN
;
329 if (strcasecmp_m(username
, state
->domain_name
) == 0) {
330 *authority_name
= talloc_strdup(mem_ctx
,
332 if (*authority_name
== NULL
) {
333 return NT_STATUS_NO_MEMORY
;
335 *sid
= dom_sid_dup(mem_ctx
, state
->domain_sid
);
337 return NT_STATUS_NO_MEMORY
;
339 *rtype
= SID_NAME_DOMAIN
;
344 /* Perhaps this is a well known user? */
345 name
= talloc_asprintf(mem_ctx
, "%s\\%s", NAME_NT_AUTHORITY
, username
);
347 return NT_STATUS_NO_MEMORY
;
349 status
= dcesrv_lsa_lookup_name(ev_ctx
, lp_ctx
, state
, mem_ctx
, name
, authority_name
, sid
, rtype
, rid
);
350 if (NT_STATUS_IS_OK(status
)) {
354 /* Perhaps this is a BUILTIN user? */
355 name
= talloc_asprintf(mem_ctx
, "%s\\%s", NAME_BUILTIN
, username
);
357 return NT_STATUS_NO_MEMORY
;
359 status
= dcesrv_lsa_lookup_name(ev_ctx
, lp_ctx
, state
, mem_ctx
, name
, authority_name
, sid
, rtype
, rid
);
360 if (NT_STATUS_IS_OK(status
)) {
364 /* OK, I give up - perhaps we need to assume the user is in our domain? */
365 name
= talloc_asprintf(mem_ctx
, "%s\\%s", state
->domain_name
, username
);
367 return NT_STATUS_NO_MEMORY
;
369 status
= dcesrv_lsa_lookup_name(ev_ctx
, lp_ctx
, state
, mem_ctx
, name
, authority_name
, sid
, rtype
, rid
);
370 if (NT_STATUS_IS_OK(status
)) {
374 return STATUS_SOME_UNMAPPED
;
375 } else if (strcasecmp_m(domain
, NAME_NT_AUTHORITY
) == 0) {
377 *authority_name
= NAME_NT_AUTHORITY
;
378 *sid
= dom_sid_parse_talloc(mem_ctx
, SID_NT_AUTHORITY
);
380 return NT_STATUS_NO_MEMORY
;
382 *rtype
= SID_NAME_DOMAIN
;
383 dom_sid_split_rid(NULL
, *sid
, NULL
, rid
);
387 /* Look up table of well known names */
388 status
= lookup_well_known_names(mem_ctx
, domain
, username
, authority_name
,
390 if (NT_STATUS_IS_OK(status
)) {
391 dom_sid_split_rid(NULL
, *sid
, NULL
, rid
);
394 } else if (strcasecmp_m(domain
, NAME_BUILTIN
) == 0) {
395 *authority_name
= NAME_BUILTIN
;
396 domain_dn
= state
->builtin_dn
;
397 } else if (strcasecmp_m(domain
, state
->domain_dns
) == 0) {
398 *authority_name
= talloc_strdup(mem_ctx
,
400 if (*authority_name
== NULL
) {
401 return NT_STATUS_NO_MEMORY
;
403 domain_dn
= state
->domain_dn
;
404 } else if (strcasecmp_m(domain
, state
->domain_name
) == 0) {
405 *authority_name
= talloc_strdup(mem_ctx
,
407 if (*authority_name
== NULL
) {
408 return NT_STATUS_NO_MEMORY
;
410 domain_dn
= state
->domain_dn
;
412 /* Not local, need to ask winbind in future */
413 return STATUS_SOME_UNMAPPED
;
416 ret
= gendb_search_dn(state
->sam_ldb
, mem_ctx
, domain_dn
, &res
, attrs
);
418 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
420 domain_sid
= samdb_result_dom_sid(mem_ctx
, res
[0], "objectSid");
421 if (domain_sid
== NULL
) {
422 return NT_STATUS_INVALID_SID
;
427 *rtype
= SID_NAME_DOMAIN
;
432 ret
= gendb_search(state
->sam_ldb
, mem_ctx
, domain_dn
, &res
, attrs
,
433 "(&(sAMAccountName=%s)(objectSid=*))",
434 ldb_binary_encode_string(mem_ctx
, username
));
436 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
439 for (i
=0; i
< ret
; i
++) {
440 *sid
= samdb_result_dom_sid(mem_ctx
, res
[i
], "objectSid");
442 return NT_STATUS_INVALID_SID
;
445 /* Check that this is in the domain */
446 if (!dom_sid_in_domain(domain_sid
, *sid
)) {
450 atype
= ldb_msg_find_attr_as_uint(res
[i
], "sAMAccountType", 0);
452 *rtype
= ds_atype_map(atype
);
453 if (*rtype
== SID_NAME_UNKNOWN
) {
454 return STATUS_SOME_UNMAPPED
;
457 dom_sid_split_rid(NULL
, *sid
, NULL
, rid
);
461 /* need to check for an allocated sid */
463 return NT_STATUS_INVALID_SID
;
468 add to the lsa_RefDomainList for LookupSids and LookupNames
470 static NTSTATUS
dcesrv_lsa_authority_list(struct lsa_policy_state
*state
, TALLOC_CTX
*mem_ctx
,
471 enum lsa_SidType rtype
,
472 const char *authority_name
,
474 struct lsa_RefDomainList
*domains
,
477 struct dom_sid
*authority_sid
;
480 if (rtype
!= SID_NAME_DOMAIN
) {
481 authority_sid
= dom_sid_dup(mem_ctx
, sid
);
482 if (authority_sid
== NULL
) {
483 return NT_STATUS_NO_MEMORY
;
485 authority_sid
->num_auths
--;
490 /* see if we've already done this authority name */
491 for (i
=0;i
<domains
->count
;i
++) {
492 if (strcasecmp_m(authority_name
, domains
->domains
[i
].name
.string
) == 0) {
498 domains
->domains
= talloc_realloc(domains
,
500 struct lsa_DomainInfo
,
502 if (domains
->domains
== NULL
) {
503 return NT_STATUS_NO_MEMORY
;
505 domains
->domains
[i
].name
.string
= authority_name
;
506 domains
->domains
[i
].sid
= authority_sid
;
508 domains
->max_size
= LSA_REF_DOMAIN_LIST_MULTIPLIER
* domains
->count
;
515 lookup a name for 1 SID
517 static NTSTATUS
dcesrv_lsa_lookup_sid(struct lsa_policy_state
*state
, TALLOC_CTX
*mem_ctx
,
518 struct dom_sid
*sid
, const char *sid_str
,
519 const char **authority_name
,
520 const char **name
, enum lsa_SidType
*rtype
)
525 struct ldb_message
**res
;
526 struct ldb_dn
*domain_dn
;
527 const char * const attrs
[] = { "sAMAccountName", "sAMAccountType", "cn", NULL
};
529 status
= lookup_well_known_sids(mem_ctx
, sid_str
, authority_name
, name
, rtype
);
530 if (NT_STATUS_IS_OK(status
)) {
534 if (dom_sid_equal(state
->domain_sid
, sid
)) {
535 *authority_name
= talloc_strdup(mem_ctx
, state
->domain_name
);
536 if (*authority_name
== NULL
) {
537 return NT_STATUS_NO_MEMORY
;
540 *rtype
= SID_NAME_DOMAIN
;
544 if (dom_sid_in_domain(state
->domain_sid
, sid
)) {
545 *authority_name
= talloc_strdup(mem_ctx
, state
->domain_name
);
546 if (*authority_name
== NULL
) {
547 return NT_STATUS_NO_MEMORY
;
549 domain_dn
= state
->domain_dn
;
550 } else if (dom_sid_in_domain(state
->builtin_sid
, sid
)) {
551 *authority_name
= NAME_BUILTIN
;
552 domain_dn
= state
->builtin_dn
;
554 /* Not well known, our domain or built in */
556 /* In future, we must look at SID histories, and at trusted domains via winbind */
558 return NT_STATUS_NOT_FOUND
;
561 /* need to re-add a check for an allocated sid */
563 ret
= gendb_search(state
->sam_ldb
, mem_ctx
, domain_dn
, &res
, attrs
,
564 "objectSid=%s", ldap_encode_ndr_dom_sid(mem_ctx
, sid
));
565 if ((ret
< 0) || (ret
> 1)) {
566 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
569 return NT_STATUS_NOT_FOUND
;
572 *name
= ldb_msg_find_attr_as_string(res
[0], "sAMAccountName", NULL
);
574 *name
= ldb_msg_find_attr_as_string(res
[0], "cn", NULL
);
576 *name
= talloc_strdup(mem_ctx
, sid_str
);
577 NT_STATUS_HAVE_NO_MEMORY(*name
);
581 atype
= ldb_msg_find_attr_as_uint(res
[0], "sAMAccountType", 0);
582 *rtype
= ds_atype_map(atype
);
587 static NTSTATUS
dcesrv_lsa_LookupSids_common(struct dcesrv_call_state
*dce_call
,
589 struct lsa_policy_state
*state
,
590 struct lsa_LookupSids2
*r
)
592 struct lsa_RefDomainList
*domains
= NULL
;
593 NTSTATUS status
= NT_STATUS_OK
;
596 if (r
->in
.level
< LSA_LOOKUP_NAMES_ALL
||
597 r
->in
.level
> LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC
) {
598 return NT_STATUS_INVALID_PARAMETER
;
601 *r
->out
.domains
= NULL
;
603 /* NOTE: the WSPP test suite tries SIDs with invalid revision numbers,
604 and expects NT_STATUS_INVALID_PARAMETER back - we just treat it as
605 an unknown SID. We could add a SID validator here. (tridge)
609 domains
= talloc_zero(r
->out
.domains
, struct lsa_RefDomainList
);
610 if (domains
== NULL
) {
611 return NT_STATUS_NO_MEMORY
;
613 *r
->out
.domains
= domains
;
615 r
->out
.names
= talloc_zero(mem_ctx
, struct lsa_TransNameArray2
);
616 if (r
->out
.names
== NULL
) {
617 return NT_STATUS_NO_MEMORY
;
622 r
->out
.names
->names
= talloc_array(r
->out
.names
, struct lsa_TranslatedName2
,
623 r
->in
.sids
->num_sids
);
624 if (r
->out
.names
->names
== NULL
) {
625 return NT_STATUS_NO_MEMORY
;
628 for (i
=0;i
<r
->in
.sids
->num_sids
;i
++) {
629 struct dom_sid
*sid
= r
->in
.sids
->sids
[i
].sid
;
630 char *sid_str
= dom_sid_string(mem_ctx
, sid
);
631 const char *name
, *authority_name
;
632 enum lsa_SidType rtype
;
636 r
->out
.names
->count
++;
638 r
->out
.names
->names
[i
].sid_type
= SID_NAME_UNKNOWN
;
639 r
->out
.names
->names
[i
].name
.string
= sid_str
;
640 r
->out
.names
->names
[i
].sid_index
= 0xFFFFFFFF;
641 r
->out
.names
->names
[i
].unknown
= 0;
643 if (sid_str
== NULL
) {
644 r
->out
.names
->names
[i
].name
.string
= "(SIDERROR)";
645 status
= STATUS_SOME_UNMAPPED
;
649 status2
= dcesrv_lsa_lookup_sid(state
, mem_ctx
, sid
, sid_str
,
650 &authority_name
, &name
, &rtype
);
651 if (!NT_STATUS_IS_OK(status2
)) {
652 status
= STATUS_SOME_UNMAPPED
;
656 /* set up the authority table */
657 status2
= dcesrv_lsa_authority_list(state
, mem_ctx
, rtype
,
659 domains
, &sid_index
);
660 if (!NT_STATUS_IS_OK(status2
)) {
664 r
->out
.names
->names
[i
].sid_type
= rtype
;
665 r
->out
.names
->names
[i
].name
.string
= name
;
666 r
->out
.names
->names
[i
].sid_index
= sid_index
;
667 r
->out
.names
->names
[i
].unknown
= 0;
672 if (*r
->out
.count
== 0) {
673 return NT_STATUS_NONE_MAPPED
;
675 if (*r
->out
.count
!= r
->in
.sids
->num_sids
) {
676 return STATUS_SOME_UNMAPPED
;
685 NTSTATUS
dcesrv_lsa_LookupSids2(struct dcesrv_call_state
*dce_call
,
687 struct lsa_LookupSids2
*r
)
689 enum dcerpc_transport_t transport
=
690 dcerpc_binding_get_transport(dce_call
->conn
->endpoint
->ep_description
);
691 struct lsa_policy_state
*state
;
692 struct dcesrv_handle
*h
;
694 if (transport
!= NCACN_NP
&& transport
!= NCALRPC
) {
695 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED
);
698 DCESRV_PULL_HANDLE(h
, r
->in
.handle
, LSA_HANDLE_POLICY
);
702 return dcesrv_lsa_LookupSids_common(dce_call
,
712 Identical to LookupSids2, but doesn't take a policy handle
715 NTSTATUS
dcesrv_lsa_LookupSids3(struct dcesrv_call_state
*dce_call
,
717 struct lsa_LookupSids3
*r
)
719 enum dcerpc_transport_t transport
=
720 dcerpc_binding_get_transport(dce_call
->conn
->endpoint
->ep_description
);
721 struct dcerpc_auth
*auth_info
= dce_call
->conn
->auth_state
.auth_info
;
722 struct lsa_policy_state
*policy_state
;
723 struct lsa_LookupSids2 q
;
726 if (transport
!= NCACN_IP_TCP
) {
727 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED
);
731 * We don't have policy handles on this call. So this must be restricted
732 * to crypto connections only.
734 if (auth_info
->auth_type
!= DCERPC_AUTH_TYPE_SCHANNEL
||
735 auth_info
->auth_level
< DCERPC_AUTH_LEVEL_INTEGRITY
) {
736 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED
);
739 status
= dcesrv_lsa_get_policy_state(dce_call
, mem_ctx
, &policy_state
);
740 if (!NT_STATUS_IS_OK(status
)) {
747 q
.in
.sids
= r
->in
.sids
;
748 q
.in
.names
= r
->in
.names
;
749 q
.in
.level
= r
->in
.level
;
750 q
.in
.count
= r
->in
.count
;
751 q
.in
.lookup_options
= r
->in
.lookup_options
;
752 q
.in
.client_revision
= r
->in
.client_revision
;
753 q
.out
.count
= r
->out
.count
;
754 q
.out
.names
= r
->out
.names
;
755 q
.out
.domains
= r
->out
.domains
;
757 status
= dcesrv_lsa_LookupSids_common(dce_call
,
762 talloc_free(policy_state
);
764 r
->out
.count
= q
.out
.count
;
765 r
->out
.names
= q
.out
.names
;
766 r
->out
.domains
= q
.out
.domains
;
775 NTSTATUS
dcesrv_lsa_LookupSids(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
776 struct lsa_LookupSids
*r
)
778 enum dcerpc_transport_t transport
=
779 dcerpc_binding_get_transport(dce_call
->conn
->endpoint
->ep_description
);
780 struct lsa_LookupSids2 r2
;
784 if (transport
!= NCACN_NP
&& transport
!= NCALRPC
) {
785 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED
);
790 r2
.in
.handle
= r
->in
.handle
;
791 r2
.in
.sids
= r
->in
.sids
;
793 r2
.in
.level
= r
->in
.level
;
794 r2
.in
.count
= r
->in
.count
;
795 r2
.in
.lookup_options
= 0;
796 r2
.in
.client_revision
= 0;
797 r2
.out
.count
= r
->out
.count
;
799 r2
.out
.domains
= r
->out
.domains
;
801 status
= dcesrv_lsa_LookupSids2(dce_call
, mem_ctx
, &r2
);
802 /* we deliberately don't check for error from the above,
803 as even on error we are supposed to return the names */
805 r
->out
.domains
= r2
.out
.domains
;
811 r
->out
.names
= talloc(mem_ctx
, struct lsa_TransNameArray
);
812 if (r
->out
.names
== NULL
) {
813 return NT_STATUS_NO_MEMORY
;
815 r
->out
.names
->count
= r2
.out
.names
->count
;
816 r
->out
.names
->names
= talloc_array(r
->out
.names
, struct lsa_TranslatedName
,
817 r
->out
.names
->count
);
818 if (r
->out
.names
->names
== NULL
) {
819 return NT_STATUS_NO_MEMORY
;
821 for (i
=0;i
<r
->out
.names
->count
;i
++) {
822 r
->out
.names
->names
[i
].sid_type
= r2
.out
.names
->names
[i
].sid_type
;
823 r
->out
.names
->names
[i
].name
.string
= r2
.out
.names
->names
[i
].name
.string
;
824 r
->out
.names
->names
[i
].sid_index
= r2
.out
.names
->names
[i
].sid_index
;
830 static NTSTATUS
dcesrv_lsa_LookupNames_common(struct dcesrv_call_state
*dce_call
,
832 struct lsa_policy_state
*policy_state
,
833 struct lsa_LookupNames3
*r
)
835 struct loadparm_context
*lp_ctx
= dce_call
->conn
->dce_ctx
->lp_ctx
;
836 struct lsa_RefDomainList
*domains
;
839 if (r
->in
.level
< LSA_LOOKUP_NAMES_ALL
||
840 r
->in
.level
> LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC
) {
841 return NT_STATUS_INVALID_PARAMETER
;
844 *r
->out
.domains
= NULL
;
846 domains
= talloc_zero(mem_ctx
, struct lsa_RefDomainList
);
847 if (domains
== NULL
) {
848 return NT_STATUS_NO_MEMORY
;
850 *r
->out
.domains
= domains
;
852 r
->out
.sids
= talloc_zero(mem_ctx
, struct lsa_TransSidArray3
);
853 if (r
->out
.sids
== NULL
) {
854 return NT_STATUS_NO_MEMORY
;
859 r
->out
.sids
->sids
= talloc_array(r
->out
.sids
, struct lsa_TranslatedSid3
,
861 if (r
->out
.sids
->sids
== NULL
) {
862 return NT_STATUS_NO_MEMORY
;
865 for (i
=0;i
<r
->in
.num_names
;i
++) {
866 const char *name
= r
->in
.names
[i
].string
;
867 const char *authority_name
;
869 uint32_t sid_index
, rid
;
870 enum lsa_SidType rtype
;
873 r
->out
.sids
->count
++;
875 r
->out
.sids
->sids
[i
].sid_type
= SID_NAME_UNKNOWN
;
876 r
->out
.sids
->sids
[i
].sid
= NULL
;
877 r
->out
.sids
->sids
[i
].sid_index
= 0xFFFFFFFF;
878 r
->out
.sids
->sids
[i
].flags
= 0;
880 status2
= dcesrv_lsa_lookup_name(dce_call
->event_ctx
, lp_ctx
, policy_state
, mem_ctx
, name
,
881 &authority_name
, &sid
, &rtype
, &rid
);
882 if (!NT_STATUS_IS_OK(status2
) || sid
->num_auths
== 0) {
886 status2
= dcesrv_lsa_authority_list(policy_state
, mem_ctx
, rtype
, authority_name
,
887 sid
, domains
, &sid_index
);
888 if (!NT_STATUS_IS_OK(status2
)) {
892 r
->out
.sids
->sids
[i
].sid_type
= rtype
;
893 r
->out
.sids
->sids
[i
].sid
= sid
;
894 r
->out
.sids
->sids
[i
].sid_index
= sid_index
;
895 r
->out
.sids
->sids
[i
].flags
= 0;
900 if (*r
->out
.count
== 0) {
901 return NT_STATUS_NONE_MAPPED
;
903 if (*r
->out
.count
!= r
->in
.num_names
) {
904 return STATUS_SOME_UNMAPPED
;
913 NTSTATUS
dcesrv_lsa_LookupNames3(struct dcesrv_call_state
*dce_call
,
915 struct lsa_LookupNames3
*r
)
917 enum dcerpc_transport_t transport
=
918 dcerpc_binding_get_transport(dce_call
->conn
->endpoint
->ep_description
);
919 struct lsa_policy_state
*policy_state
;
920 struct dcesrv_handle
*policy_handle
;
922 if (transport
!= NCACN_NP
&& transport
!= NCALRPC
) {
923 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED
);
926 DCESRV_PULL_HANDLE(policy_handle
, r
->in
.handle
, LSA_HANDLE_POLICY
);
928 policy_state
= policy_handle
->data
;
930 return dcesrv_lsa_LookupNames_common(dce_call
,
939 Identical to LookupNames3, but doesn't take a policy handle
942 NTSTATUS
dcesrv_lsa_LookupNames4(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
943 struct lsa_LookupNames4
*r
)
945 enum dcerpc_transport_t transport
=
946 dcerpc_binding_get_transport(dce_call
->conn
->endpoint
->ep_description
);
947 struct dcerpc_auth
*auth_info
= dce_call
->conn
->auth_state
.auth_info
;
948 struct lsa_policy_state
*policy_state
;
949 struct lsa_LookupNames3 q
;
952 if (transport
!= NCACN_IP_TCP
) {
953 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED
);
957 * We don't have policy handles on this call. So this must be restricted
958 * to crypto connections only.
960 if (auth_info
->auth_type
!= DCERPC_AUTH_TYPE_SCHANNEL
||
961 auth_info
->auth_level
< DCERPC_AUTH_LEVEL_INTEGRITY
) {
962 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED
);
965 status
= dcesrv_lsa_get_policy_state(dce_call
, mem_ctx
, &policy_state
);
966 if (!NT_STATUS_IS_OK(status
)) {
973 q
.in
.num_names
= r
->in
.num_names
;
974 q
.in
.names
= r
->in
.names
;
975 q
.in
.level
= r
->in
.level
;
976 q
.in
.sids
= r
->in
.sids
;
977 q
.in
.count
= r
->in
.count
;
978 q
.in
.lookup_options
= r
->in
.lookup_options
;
979 q
.in
.client_revision
= r
->in
.client_revision
;
981 q
.out
.count
= r
->out
.count
;
982 q
.out
.sids
= r
->out
.sids
;
983 q
.out
.domains
= r
->out
.domains
;
985 status
= dcesrv_lsa_LookupNames_common(dce_call
,
990 talloc_free(policy_state
);
992 r
->out
.count
= q
.out
.count
;
993 r
->out
.sids
= q
.out
.sids
;
994 r
->out
.domains
= q
.out
.domains
;
1002 NTSTATUS
dcesrv_lsa_LookupNames2(struct dcesrv_call_state
*dce_call
,
1003 TALLOC_CTX
*mem_ctx
,
1004 struct lsa_LookupNames2
*r
)
1006 enum dcerpc_transport_t transport
=
1007 dcerpc_binding_get_transport(dce_call
->conn
->endpoint
->ep_description
);
1008 struct lsa_policy_state
*state
;
1009 struct dcesrv_handle
*h
;
1011 struct loadparm_context
*lp_ctx
= dce_call
->conn
->dce_ctx
->lp_ctx
;
1012 struct lsa_RefDomainList
*domains
;
1014 if (transport
!= NCACN_NP
&& transport
!= NCALRPC
) {
1015 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED
);
1018 *r
->out
.domains
= NULL
;
1020 DCESRV_PULL_HANDLE(h
, r
->in
.handle
, LSA_HANDLE_POLICY
);
1022 if (r
->in
.level
< LSA_LOOKUP_NAMES_ALL
||
1023 r
->in
.level
> LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC
) {
1024 return NT_STATUS_INVALID_PARAMETER
;
1029 domains
= talloc_zero(mem_ctx
, struct lsa_RefDomainList
);
1030 if (domains
== NULL
) {
1031 return NT_STATUS_NO_MEMORY
;
1033 *r
->out
.domains
= domains
;
1035 r
->out
.sids
= talloc_zero(mem_ctx
, struct lsa_TransSidArray2
);
1036 if (r
->out
.sids
== NULL
) {
1037 return NT_STATUS_NO_MEMORY
;
1042 r
->out
.sids
->sids
= talloc_array(r
->out
.sids
, struct lsa_TranslatedSid2
,
1044 if (r
->out
.sids
->sids
== NULL
) {
1045 return NT_STATUS_NO_MEMORY
;
1048 for (i
=0;i
<r
->in
.num_names
;i
++) {
1049 const char *name
= r
->in
.names
[i
].string
;
1050 const char *authority_name
;
1051 struct dom_sid
*sid
;
1052 uint32_t sid_index
, rid
=0;
1053 enum lsa_SidType rtype
;
1056 r
->out
.sids
->count
++;
1058 r
->out
.sids
->sids
[i
].sid_type
= SID_NAME_UNKNOWN
;
1059 /* MS-LSAT 3.1.4.7 - rid zero is considered equivalent
1060 to sid NULL - so we should return 0 rid for
1062 r
->out
.sids
->sids
[i
].rid
= 0;
1063 r
->out
.sids
->sids
[i
].sid_index
= 0xFFFFFFFF;
1064 r
->out
.sids
->sids
[i
].unknown
= 0;
1066 status2
= dcesrv_lsa_lookup_name(dce_call
->event_ctx
, lp_ctx
, state
, mem_ctx
, name
,
1067 &authority_name
, &sid
, &rtype
, &rid
);
1068 if (!NT_STATUS_IS_OK(status2
)) {
1072 status2
= dcesrv_lsa_authority_list(state
, mem_ctx
, rtype
, authority_name
,
1073 sid
, domains
, &sid_index
);
1074 if (!NT_STATUS_IS_OK(status2
)) {
1078 r
->out
.sids
->sids
[i
].sid_type
= rtype
;
1079 r
->out
.sids
->sids
[i
].rid
= rid
;
1080 r
->out
.sids
->sids
[i
].sid_index
= sid_index
;
1081 r
->out
.sids
->sids
[i
].unknown
= 0;
1086 if (*r
->out
.count
== 0) {
1087 return NT_STATUS_NONE_MAPPED
;
1089 if (*r
->out
.count
!= r
->in
.num_names
) {
1090 return STATUS_SOME_UNMAPPED
;
1093 return NT_STATUS_OK
;
1099 NTSTATUS
dcesrv_lsa_LookupNames(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1100 struct lsa_LookupNames
*r
)
1102 enum dcerpc_transport_t transport
=
1103 dcerpc_binding_get_transport(dce_call
->conn
->endpoint
->ep_description
);
1104 struct lsa_LookupNames2 r2
;
1108 if (transport
!= NCACN_NP
&& transport
!= NCALRPC
) {
1109 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED
);
1114 r2
.in
.handle
= r
->in
.handle
;
1115 r2
.in
.num_names
= r
->in
.num_names
;
1116 r2
.in
.names
= r
->in
.names
;
1118 r2
.in
.level
= r
->in
.level
;
1119 r2
.in
.count
= r
->in
.count
;
1120 r2
.in
.lookup_options
= 0;
1121 r2
.in
.client_revision
= 0;
1122 r2
.out
.count
= r
->out
.count
;
1123 r2
.out
.domains
= r
->out
.domains
;
1125 status
= dcesrv_lsa_LookupNames2(dce_call
, mem_ctx
, &r2
);
1126 if (r2
.out
.sids
== NULL
) {
1130 r
->out
.sids
= talloc(mem_ctx
, struct lsa_TransSidArray
);
1131 if (r
->out
.sids
== NULL
) {
1132 return NT_STATUS_NO_MEMORY
;
1134 r
->out
.sids
->count
= r2
.out
.sids
->count
;
1135 r
->out
.sids
->sids
= talloc_array(r
->out
.sids
, struct lsa_TranslatedSid
,
1136 r
->out
.sids
->count
);
1137 if (r
->out
.sids
->sids
== NULL
) {
1138 return NT_STATUS_NO_MEMORY
;
1140 for (i
=0;i
<r
->out
.sids
->count
;i
++) {
1141 r
->out
.sids
->sids
[i
].sid_type
= r2
.out
.sids
->sids
[i
].sid_type
;
1142 r
->out
.sids
->sids
[i
].rid
= r2
.out
.sids
->sids
[i
].rid
;
1143 r
->out
.sids
->sids
[i
].sid_index
= r2
.out
.sids
->sids
[i
].sid_index
;