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
);
287 *rtype
= SID_NAME_DOMAIN
;
292 if (strcasecmp_m(username
, NAME_NT_AUTHORITY
) == 0) {
293 *authority_name
= NAME_NT_AUTHORITY
;
294 *sid
= dom_sid_parse_talloc(mem_ctx
, SID_NT_AUTHORITY
);
295 *rtype
= SID_NAME_DOMAIN
;
296 dom_sid_split_rid(NULL
, *sid
, NULL
, rid
);
299 if (strcasecmp_m(username
, NAME_BUILTIN
) == 0) {
300 *authority_name
= NAME_BUILTIN
;
301 *sid
= dom_sid_parse_talloc(mem_ctx
, SID_BUILTIN
);
302 *rtype
= SID_NAME_DOMAIN
;
306 if (strcasecmp_m(username
, state
->domain_dns
) == 0) {
307 *authority_name
= state
->domain_name
;
308 *sid
= state
->domain_sid
;
309 *rtype
= SID_NAME_DOMAIN
;
313 if (strcasecmp_m(username
, state
->domain_name
) == 0) {
314 *authority_name
= state
->domain_name
;
315 *sid
= state
->domain_sid
;
316 *rtype
= SID_NAME_DOMAIN
;
321 /* Perhaps this is a well known user? */
322 name
= talloc_asprintf(mem_ctx
, "%s\\%s", NAME_NT_AUTHORITY
, username
);
324 return NT_STATUS_NO_MEMORY
;
326 status
= dcesrv_lsa_lookup_name(ev_ctx
, lp_ctx
, state
, mem_ctx
, name
, authority_name
, sid
, rtype
, rid
);
327 if (NT_STATUS_IS_OK(status
)) {
331 /* Perhaps this is a BUILTIN user? */
332 name
= talloc_asprintf(mem_ctx
, "%s\\%s", NAME_BUILTIN
, username
);
334 return NT_STATUS_NO_MEMORY
;
336 status
= dcesrv_lsa_lookup_name(ev_ctx
, lp_ctx
, state
, mem_ctx
, name
, authority_name
, sid
, rtype
, rid
);
337 if (NT_STATUS_IS_OK(status
)) {
341 /* OK, I give up - perhaps we need to assume the user is in our domain? */
342 name
= talloc_asprintf(mem_ctx
, "%s\\%s", state
->domain_name
, username
);
344 return NT_STATUS_NO_MEMORY
;
346 status
= dcesrv_lsa_lookup_name(ev_ctx
, lp_ctx
, state
, mem_ctx
, name
, authority_name
, sid
, rtype
, rid
);
347 if (NT_STATUS_IS_OK(status
)) {
351 return STATUS_SOME_UNMAPPED
;
352 } else if (strcasecmp_m(domain
, NAME_NT_AUTHORITY
) == 0) {
354 *authority_name
= NAME_NT_AUTHORITY
;
355 *sid
= dom_sid_parse_talloc(mem_ctx
, SID_NT_AUTHORITY
);
356 *rtype
= SID_NAME_DOMAIN
;
357 dom_sid_split_rid(NULL
, *sid
, NULL
, rid
);
361 /* Look up table of well known names */
362 status
= lookup_well_known_names(mem_ctx
, domain
, username
, authority_name
,
364 if (NT_STATUS_IS_OK(status
)) {
365 dom_sid_split_rid(NULL
, *sid
, NULL
, rid
);
368 } else if (strcasecmp_m(domain
, NAME_BUILTIN
) == 0) {
369 *authority_name
= NAME_BUILTIN
;
370 domain_dn
= state
->builtin_dn
;
371 } else if (strcasecmp_m(domain
, state
->domain_dns
) == 0) {
372 *authority_name
= state
->domain_name
;
373 domain_dn
= state
->domain_dn
;
374 } else if (strcasecmp_m(domain
, state
->domain_name
) == 0) {
375 *authority_name
= state
->domain_name
;
376 domain_dn
= state
->domain_dn
;
378 /* Not local, need to ask winbind in future */
379 return STATUS_SOME_UNMAPPED
;
382 ret
= gendb_search_dn(state
->sam_ldb
, mem_ctx
, domain_dn
, &res
, attrs
);
384 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
386 domain_sid
= samdb_result_dom_sid(mem_ctx
, res
[0], "objectSid");
387 if (domain_sid
== NULL
) {
388 return NT_STATUS_INVALID_SID
;
393 *rtype
= SID_NAME_DOMAIN
;
398 ret
= gendb_search(state
->sam_ldb
, mem_ctx
, domain_dn
, &res
, attrs
,
399 "(&(sAMAccountName=%s)(objectSid=*))",
400 ldb_binary_encode_string(mem_ctx
, username
));
402 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
405 for (i
=0; i
< ret
; i
++) {
406 *sid
= samdb_result_dom_sid(mem_ctx
, res
[i
], "objectSid");
408 return NT_STATUS_INVALID_SID
;
411 /* Check that this is in the domain */
412 if (!dom_sid_in_domain(domain_sid
, *sid
)) {
416 atype
= ldb_msg_find_attr_as_uint(res
[i
], "sAMAccountType", 0);
418 *rtype
= ds_atype_map(atype
);
419 if (*rtype
== SID_NAME_UNKNOWN
) {
420 return STATUS_SOME_UNMAPPED
;
423 dom_sid_split_rid(NULL
, *sid
, NULL
, rid
);
427 /* need to check for an allocated sid */
429 return NT_STATUS_INVALID_SID
;
434 add to the lsa_RefDomainList for LookupSids and LookupNames
436 static NTSTATUS
dcesrv_lsa_authority_list(struct lsa_policy_state
*state
, TALLOC_CTX
*mem_ctx
,
437 enum lsa_SidType rtype
,
438 const char *authority_name
,
440 struct lsa_RefDomainList
*domains
,
443 struct dom_sid
*authority_sid
;
446 if (rtype
!= SID_NAME_DOMAIN
) {
447 authority_sid
= dom_sid_dup(mem_ctx
, sid
);
448 if (authority_sid
== NULL
) {
449 return NT_STATUS_NO_MEMORY
;
451 authority_sid
->num_auths
--;
456 /* see if we've already done this authority name */
457 for (i
=0;i
<domains
->count
;i
++) {
458 if (strcasecmp_m(authority_name
, domains
->domains
[i
].name
.string
) == 0) {
464 domains
->domains
= talloc_realloc(domains
,
466 struct lsa_DomainInfo
,
468 if (domains
->domains
== NULL
) {
469 return NT_STATUS_NO_MEMORY
;
471 domains
->domains
[i
].name
.string
= authority_name
;
472 domains
->domains
[i
].sid
= authority_sid
;
474 domains
->max_size
= LSA_REF_DOMAIN_LIST_MULTIPLIER
* domains
->count
;
481 lookup a name for 1 SID
483 static NTSTATUS
dcesrv_lsa_lookup_sid(struct lsa_policy_state
*state
, TALLOC_CTX
*mem_ctx
,
484 struct dom_sid
*sid
, const char *sid_str
,
485 const char **authority_name
,
486 const char **name
, enum lsa_SidType
*rtype
)
491 struct ldb_message
**res
;
492 struct ldb_dn
*domain_dn
;
493 const char * const attrs
[] = { "sAMAccountName", "sAMAccountType", "cn", NULL
};
495 status
= lookup_well_known_sids(mem_ctx
, sid_str
, authority_name
, name
, rtype
);
496 if (NT_STATUS_IS_OK(status
)) {
500 if (dom_sid_in_domain(state
->domain_sid
, sid
)) {
501 *authority_name
= state
->domain_name
;
502 domain_dn
= state
->domain_dn
;
503 } else if (dom_sid_in_domain(state
->builtin_sid
, sid
)) {
504 *authority_name
= NAME_BUILTIN
;
505 domain_dn
= state
->builtin_dn
;
507 /* Not well known, our domain or built in */
509 /* In future, we must look at SID histories, and at trusted domains via winbind */
511 return NT_STATUS_NOT_FOUND
;
514 /* need to re-add a check for an allocated sid */
516 ret
= gendb_search(state
->sam_ldb
, mem_ctx
, domain_dn
, &res
, attrs
,
517 "objectSid=%s", ldap_encode_ndr_dom_sid(mem_ctx
, sid
));
518 if ((ret
< 0) || (ret
> 1)) {
519 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
522 return NT_STATUS_NOT_FOUND
;
525 *name
= ldb_msg_find_attr_as_string(res
[0], "sAMAccountName", NULL
);
527 *name
= ldb_msg_find_attr_as_string(res
[0], "cn", NULL
);
529 *name
= talloc_strdup(mem_ctx
, sid_str
);
530 NT_STATUS_HAVE_NO_MEMORY(*name
);
534 atype
= ldb_msg_find_attr_as_uint(res
[0], "sAMAccountType", 0);
535 *rtype
= ds_atype_map(atype
);
540 static NTSTATUS
dcesrv_lsa_LookupSids_common(struct dcesrv_call_state
*dce_call
,
542 struct lsa_policy_state
*state
,
543 struct lsa_LookupSids2
*r
)
545 struct lsa_RefDomainList
*domains
= NULL
;
546 NTSTATUS status
= NT_STATUS_OK
;
549 if (r
->in
.level
< LSA_LOOKUP_NAMES_ALL
||
550 r
->in
.level
> LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC
) {
551 return NT_STATUS_INVALID_PARAMETER
;
554 *r
->out
.domains
= NULL
;
556 /* NOTE: the WSPP test suite tries SIDs with invalid revision numbers,
557 and expects NT_STATUS_INVALID_PARAMETER back - we just treat it as
558 an unknown SID. We could add a SID validator here. (tridge)
562 domains
= talloc_zero(r
->out
.domains
, struct lsa_RefDomainList
);
563 if (domains
== NULL
) {
564 return NT_STATUS_NO_MEMORY
;
566 *r
->out
.domains
= domains
;
568 r
->out
.names
= talloc_zero(mem_ctx
, struct lsa_TransNameArray2
);
569 if (r
->out
.names
== NULL
) {
570 return NT_STATUS_NO_MEMORY
;
575 r
->out
.names
->names
= talloc_array(r
->out
.names
, struct lsa_TranslatedName2
,
576 r
->in
.sids
->num_sids
);
577 if (r
->out
.names
->names
== NULL
) {
578 return NT_STATUS_NO_MEMORY
;
581 for (i
=0;i
<r
->in
.sids
->num_sids
;i
++) {
582 struct dom_sid
*sid
= r
->in
.sids
->sids
[i
].sid
;
583 char *sid_str
= dom_sid_string(mem_ctx
, sid
);
584 const char *name
, *authority_name
;
585 enum lsa_SidType rtype
;
589 r
->out
.names
->count
++;
591 r
->out
.names
->names
[i
].sid_type
= SID_NAME_UNKNOWN
;
592 r
->out
.names
->names
[i
].name
.string
= sid_str
;
593 r
->out
.names
->names
[i
].sid_index
= 0xFFFFFFFF;
594 r
->out
.names
->names
[i
].unknown
= 0;
596 if (sid_str
== NULL
) {
597 r
->out
.names
->names
[i
].name
.string
= "(SIDERROR)";
598 status
= STATUS_SOME_UNMAPPED
;
602 status2
= dcesrv_lsa_lookup_sid(state
, mem_ctx
, sid
, sid_str
,
603 &authority_name
, &name
, &rtype
);
604 if (!NT_STATUS_IS_OK(status2
)) {
605 status
= STATUS_SOME_UNMAPPED
;
609 /* set up the authority table */
610 status2
= dcesrv_lsa_authority_list(state
, mem_ctx
, rtype
,
612 domains
, &sid_index
);
613 if (!NT_STATUS_IS_OK(status2
)) {
617 r
->out
.names
->names
[i
].sid_type
= rtype
;
618 r
->out
.names
->names
[i
].name
.string
= name
;
619 r
->out
.names
->names
[i
].sid_index
= sid_index
;
620 r
->out
.names
->names
[i
].unknown
= 0;
625 if (*r
->out
.count
== 0) {
626 return NT_STATUS_NONE_MAPPED
;
628 if (*r
->out
.count
!= r
->in
.sids
->num_sids
) {
629 return STATUS_SOME_UNMAPPED
;
638 NTSTATUS
dcesrv_lsa_LookupSids2(struct dcesrv_call_state
*dce_call
,
640 struct lsa_LookupSids2
*r
)
642 enum dcerpc_transport_t transport
= dce_call
->conn
->endpoint
->ep_description
->transport
;
643 struct lsa_policy_state
*state
;
644 struct dcesrv_handle
*h
;
646 if (transport
!= NCACN_NP
&& transport
!= NCALRPC
) {
647 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED
);
650 DCESRV_PULL_HANDLE(h
, r
->in
.handle
, LSA_HANDLE_POLICY
);
654 return dcesrv_lsa_LookupSids_common(dce_call
,
664 Identical to LookupSids2, but doesn't take a policy handle
667 NTSTATUS
dcesrv_lsa_LookupSids3(struct dcesrv_call_state
*dce_call
,
669 struct lsa_LookupSids3
*r
)
671 struct dcerpc_auth
*auth_info
= dce_call
->conn
->auth_state
.auth_info
;
672 struct lsa_policy_state
*policy_state
;
673 struct lsa_LookupSids2 q
;
677 * We don't have policy handles on this call. So this must be restricted
678 * to crypto connections only.
680 if (auth_info
->auth_type
!= DCERPC_AUTH_TYPE_SCHANNEL
||
681 auth_info
->auth_level
< DCERPC_AUTH_LEVEL_INTEGRITY
) {
682 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED
);
685 status
= dcesrv_lsa_get_policy_state(dce_call
, mem_ctx
, &policy_state
);
686 if (!NT_STATUS_IS_OK(status
)) {
693 q
.in
.sids
= r
->in
.sids
;
694 q
.in
.names
= r
->in
.names
;
695 q
.in
.level
= r
->in
.level
;
696 q
.in
.count
= r
->in
.count
;
697 q
.in
.lookup_options
= r
->in
.lookup_options
;
698 q
.in
.client_revision
= r
->in
.client_revision
;
699 q
.out
.count
= r
->out
.count
;
700 q
.out
.names
= r
->out
.names
;
701 q
.out
.domains
= r
->out
.domains
;
703 status
= dcesrv_lsa_LookupSids_common(dce_call
,
708 talloc_free(policy_state
);
710 r
->out
.count
= q
.out
.count
;
711 r
->out
.names
= q
.out
.names
;
712 r
->out
.domains
= q
.out
.domains
;
721 NTSTATUS
dcesrv_lsa_LookupSids(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
722 struct lsa_LookupSids
*r
)
724 enum dcerpc_transport_t transport
= dce_call
->conn
->endpoint
->ep_description
->transport
;
725 struct lsa_LookupSids2 r2
;
729 if (transport
!= NCACN_NP
&& transport
!= NCALRPC
) {
730 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED
);
735 r2
.in
.handle
= r
->in
.handle
;
736 r2
.in
.sids
= r
->in
.sids
;
738 r2
.in
.level
= r
->in
.level
;
739 r2
.in
.count
= r
->in
.count
;
740 r2
.in
.lookup_options
= 0;
741 r2
.in
.client_revision
= 0;
742 r2
.out
.count
= r
->out
.count
;
744 r2
.out
.domains
= r
->out
.domains
;
746 status
= dcesrv_lsa_LookupSids2(dce_call
, mem_ctx
, &r2
);
747 /* we deliberately don't check for error from the above,
748 as even on error we are supposed to return the names */
750 r
->out
.domains
= r2
.out
.domains
;
756 r
->out
.names
= talloc(mem_ctx
, struct lsa_TransNameArray
);
757 if (r
->out
.names
== NULL
) {
758 return NT_STATUS_NO_MEMORY
;
760 r
->out
.names
->count
= r2
.out
.names
->count
;
761 r
->out
.names
->names
= talloc_array(r
->out
.names
, struct lsa_TranslatedName
,
762 r
->out
.names
->count
);
763 if (r
->out
.names
->names
== NULL
) {
764 return NT_STATUS_NO_MEMORY
;
766 for (i
=0;i
<r
->out
.names
->count
;i
++) {
767 r
->out
.names
->names
[i
].sid_type
= r2
.out
.names
->names
[i
].sid_type
;
768 r
->out
.names
->names
[i
].name
.string
= r2
.out
.names
->names
[i
].name
.string
;
769 r
->out
.names
->names
[i
].sid_index
= r2
.out
.names
->names
[i
].sid_index
;
775 static NTSTATUS
dcesrv_lsa_LookupNames_common(struct dcesrv_call_state
*dce_call
,
777 struct lsa_policy_state
*policy_state
,
778 struct lsa_LookupNames3
*r
)
780 struct loadparm_context
*lp_ctx
= dce_call
->conn
->dce_ctx
->lp_ctx
;
781 struct lsa_RefDomainList
*domains
;
784 if (r
->in
.level
< LSA_LOOKUP_NAMES_ALL
||
785 r
->in
.level
> LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC
) {
786 return NT_STATUS_INVALID_PARAMETER
;
789 *r
->out
.domains
= NULL
;
791 domains
= talloc_zero(mem_ctx
, struct lsa_RefDomainList
);
792 if (domains
== NULL
) {
793 return NT_STATUS_NO_MEMORY
;
795 *r
->out
.domains
= domains
;
797 r
->out
.sids
= talloc_zero(mem_ctx
, struct lsa_TransSidArray3
);
798 if (r
->out
.sids
== NULL
) {
799 return NT_STATUS_NO_MEMORY
;
804 r
->out
.sids
->sids
= talloc_array(r
->out
.sids
, struct lsa_TranslatedSid3
,
806 if (r
->out
.sids
->sids
== NULL
) {
807 return NT_STATUS_NO_MEMORY
;
810 for (i
=0;i
<r
->in
.num_names
;i
++) {
811 const char *name
= r
->in
.names
[i
].string
;
812 const char *authority_name
;
814 uint32_t sid_index
, rid
;
815 enum lsa_SidType rtype
;
818 r
->out
.sids
->count
++;
820 r
->out
.sids
->sids
[i
].sid_type
= SID_NAME_UNKNOWN
;
821 r
->out
.sids
->sids
[i
].sid
= NULL
;
822 r
->out
.sids
->sids
[i
].sid_index
= 0xFFFFFFFF;
823 r
->out
.sids
->sids
[i
].flags
= 0;
825 status2
= dcesrv_lsa_lookup_name(dce_call
->event_ctx
, lp_ctx
, policy_state
, mem_ctx
, name
,
826 &authority_name
, &sid
, &rtype
, &rid
);
827 if (!NT_STATUS_IS_OK(status2
) || sid
->num_auths
== 0) {
831 status2
= dcesrv_lsa_authority_list(policy_state
, mem_ctx
, rtype
, authority_name
,
832 sid
, domains
, &sid_index
);
833 if (!NT_STATUS_IS_OK(status2
)) {
837 r
->out
.sids
->sids
[i
].sid_type
= rtype
;
838 r
->out
.sids
->sids
[i
].sid
= sid
;
839 r
->out
.sids
->sids
[i
].sid_index
= sid_index
;
840 r
->out
.sids
->sids
[i
].flags
= 0;
845 if (*r
->out
.count
== 0) {
846 return NT_STATUS_NONE_MAPPED
;
848 if (*r
->out
.count
!= r
->in
.num_names
) {
849 return STATUS_SOME_UNMAPPED
;
858 NTSTATUS
dcesrv_lsa_LookupNames3(struct dcesrv_call_state
*dce_call
,
860 struct lsa_LookupNames3
*r
)
862 enum dcerpc_transport_t transport
= dce_call
->conn
->endpoint
->ep_description
->transport
;
863 struct lsa_policy_state
*policy_state
;
864 struct dcesrv_handle
*policy_handle
;
866 if (transport
!= NCACN_NP
&& transport
!= NCALRPC
) {
867 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED
);
870 DCESRV_PULL_HANDLE(policy_handle
, r
->in
.handle
, LSA_HANDLE_POLICY
);
872 policy_state
= policy_handle
->data
;
874 return dcesrv_lsa_LookupNames_common(dce_call
,
883 Identical to LookupNames3, but doesn't take a policy handle
886 NTSTATUS
dcesrv_lsa_LookupNames4(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
887 struct lsa_LookupNames4
*r
)
889 struct dcerpc_auth
*auth_info
= dce_call
->conn
->auth_state
.auth_info
;
890 struct lsa_policy_state
*policy_state
;
891 struct lsa_LookupNames3 q
;
895 * We don't have policy handles on this call. So this must be restricted
896 * to crypto connections only.
898 if (auth_info
->auth_type
!= DCERPC_AUTH_TYPE_SCHANNEL
||
899 auth_info
->auth_level
< DCERPC_AUTH_LEVEL_INTEGRITY
) {
900 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED
);
903 status
= dcesrv_lsa_get_policy_state(dce_call
, mem_ctx
, &policy_state
);
904 if (!NT_STATUS_IS_OK(status
)) {
911 q
.in
.num_names
= r
->in
.num_names
;
912 q
.in
.names
= r
->in
.names
;
913 q
.in
.level
= r
->in
.level
;
914 q
.in
.sids
= r
->in
.sids
;
915 q
.in
.count
= r
->in
.count
;
916 q
.in
.lookup_options
= r
->in
.lookup_options
;
917 q
.in
.client_revision
= r
->in
.client_revision
;
919 q
.out
.count
= r
->out
.count
;
920 q
.out
.sids
= r
->out
.sids
;
921 q
.out
.domains
= r
->out
.domains
;
923 status
= dcesrv_lsa_LookupNames_common(dce_call
,
928 talloc_free(policy_state
);
930 r
->out
.count
= q
.out
.count
;
931 r
->out
.sids
= q
.out
.sids
;
932 r
->out
.domains
= q
.out
.domains
;
940 NTSTATUS
dcesrv_lsa_LookupNames2(struct dcesrv_call_state
*dce_call
,
942 struct lsa_LookupNames2
*r
)
944 enum dcerpc_transport_t transport
= dce_call
->conn
->endpoint
->ep_description
->transport
;
945 struct lsa_policy_state
*state
;
946 struct dcesrv_handle
*h
;
948 struct loadparm_context
*lp_ctx
= dce_call
->conn
->dce_ctx
->lp_ctx
;
949 struct lsa_RefDomainList
*domains
;
951 if (transport
!= NCACN_NP
&& transport
!= NCALRPC
) {
952 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED
);
955 *r
->out
.domains
= NULL
;
957 DCESRV_PULL_HANDLE(h
, r
->in
.handle
, LSA_HANDLE_POLICY
);
959 if (r
->in
.level
< LSA_LOOKUP_NAMES_ALL
||
960 r
->in
.level
> LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC
) {
961 return NT_STATUS_INVALID_PARAMETER
;
966 domains
= talloc_zero(mem_ctx
, struct lsa_RefDomainList
);
967 if (domains
== NULL
) {
968 return NT_STATUS_NO_MEMORY
;
970 *r
->out
.domains
= domains
;
972 r
->out
.sids
= talloc_zero(mem_ctx
, struct lsa_TransSidArray2
);
973 if (r
->out
.sids
== NULL
) {
974 return NT_STATUS_NO_MEMORY
;
979 r
->out
.sids
->sids
= talloc_array(r
->out
.sids
, struct lsa_TranslatedSid2
,
981 if (r
->out
.sids
->sids
== NULL
) {
982 return NT_STATUS_NO_MEMORY
;
985 for (i
=0;i
<r
->in
.num_names
;i
++) {
986 const char *name
= r
->in
.names
[i
].string
;
987 const char *authority_name
;
989 uint32_t sid_index
, rid
=0;
990 enum lsa_SidType rtype
;
993 r
->out
.sids
->count
++;
995 r
->out
.sids
->sids
[i
].sid_type
= SID_NAME_UNKNOWN
;
996 /* MS-LSAT 3.1.4.7 - rid zero is considered equivalent
997 to sid NULL - so we should return 0 rid for
999 r
->out
.sids
->sids
[i
].rid
= 0;
1000 r
->out
.sids
->sids
[i
].sid_index
= 0xFFFFFFFF;
1001 r
->out
.sids
->sids
[i
].unknown
= 0;
1003 status2
= dcesrv_lsa_lookup_name(dce_call
->event_ctx
, lp_ctx
, state
, mem_ctx
, name
,
1004 &authority_name
, &sid
, &rtype
, &rid
);
1005 if (!NT_STATUS_IS_OK(status2
)) {
1009 status2
= dcesrv_lsa_authority_list(state
, mem_ctx
, rtype
, authority_name
,
1010 sid
, domains
, &sid_index
);
1011 if (!NT_STATUS_IS_OK(status2
)) {
1015 r
->out
.sids
->sids
[i
].sid_type
= rtype
;
1016 r
->out
.sids
->sids
[i
].rid
= rid
;
1017 r
->out
.sids
->sids
[i
].sid_index
= sid_index
;
1018 r
->out
.sids
->sids
[i
].unknown
= 0;
1023 if (*r
->out
.count
== 0) {
1024 return NT_STATUS_NONE_MAPPED
;
1026 if (*r
->out
.count
!= r
->in
.num_names
) {
1027 return STATUS_SOME_UNMAPPED
;
1030 return NT_STATUS_OK
;
1036 NTSTATUS
dcesrv_lsa_LookupNames(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1037 struct lsa_LookupNames
*r
)
1039 enum dcerpc_transport_t transport
= dce_call
->conn
->endpoint
->ep_description
->transport
;
1040 struct lsa_LookupNames2 r2
;
1044 if (transport
!= NCACN_NP
&& transport
!= NCALRPC
) {
1045 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED
);
1050 r2
.in
.handle
= r
->in
.handle
;
1051 r2
.in
.num_names
= r
->in
.num_names
;
1052 r2
.in
.names
= r
->in
.names
;
1054 r2
.in
.level
= r
->in
.level
;
1055 r2
.in
.count
= r
->in
.count
;
1056 r2
.in
.lookup_options
= 0;
1057 r2
.in
.client_revision
= 0;
1058 r2
.out
.count
= r
->out
.count
;
1059 r2
.out
.domains
= r
->out
.domains
;
1061 status
= dcesrv_lsa_LookupNames2(dce_call
, mem_ctx
, &r2
);
1062 if (r2
.out
.sids
== NULL
) {
1066 r
->out
.sids
= talloc(mem_ctx
, struct lsa_TransSidArray
);
1067 if (r
->out
.sids
== NULL
) {
1068 return NT_STATUS_NO_MEMORY
;
1070 r
->out
.sids
->count
= r2
.out
.sids
->count
;
1071 r
->out
.sids
->sids
= talloc_array(r
->out
.sids
, struct lsa_TranslatedSid
,
1072 r
->out
.sids
->count
);
1073 if (r
->out
.sids
->sids
== NULL
) {
1074 return NT_STATUS_NO_MEMORY
;
1076 for (i
=0;i
<r
->out
.sids
->count
;i
++) {
1077 r
->out
.sids
->sids
[i
].sid_type
= r2
.out
.sids
->sids
[i
].sid_type
;
1078 r
->out
.sids
->sids
[i
].rid
= r2
.out
.sids
->sids
[i
].rid
;
1079 r
->out
.sids
->sids
[i
].sid_index
= r2
.out
.sids
->sids
[i
].sid_index
;