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
,
268 DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL
,
269 name
, &domain
, &username
);
270 if (!NT_STATUS_IS_OK(status
)) {
271 DEBUG(3, ("Failed to crack name %s into an NT4 name: %s\n", name
, nt_errstr(status
)));
280 /* Look up table of well known names */
281 status
= lookup_well_known_names(mem_ctx
, NULL
, username
, authority_name
, sid
, rtype
);
282 if (NT_STATUS_IS_OK(status
)) {
283 dom_sid_split_rid(NULL
, *sid
, NULL
, rid
);
287 if (username
== NULL
) {
288 *authority_name
= NAME_BUILTIN
;
289 *sid
= dom_sid_parse_talloc(mem_ctx
, SID_BUILTIN
);
291 return NT_STATUS_NO_MEMORY
;
293 *rtype
= SID_NAME_DOMAIN
;
298 if (strcasecmp_m(username
, NAME_NT_AUTHORITY
) == 0) {
299 *authority_name
= NAME_NT_AUTHORITY
;
300 *sid
= dom_sid_parse_talloc(mem_ctx
, SID_NT_AUTHORITY
);
302 return NT_STATUS_NO_MEMORY
;
304 *rtype
= SID_NAME_DOMAIN
;
305 dom_sid_split_rid(NULL
, *sid
, NULL
, rid
);
308 if (strcasecmp_m(username
, NAME_BUILTIN
) == 0) {
309 *authority_name
= NAME_BUILTIN
;
310 *sid
= dom_sid_parse_talloc(mem_ctx
, SID_BUILTIN
);
312 return NT_STATUS_NO_MEMORY
;
314 *rtype
= SID_NAME_DOMAIN
;
318 if (strcasecmp_m(username
, state
->domain_dns
) == 0) {
319 *authority_name
= talloc_strdup(mem_ctx
,
321 if (*authority_name
== NULL
) {
322 return NT_STATUS_NO_MEMORY
;
324 *sid
= dom_sid_dup(mem_ctx
, state
->domain_sid
);
326 return NT_STATUS_NO_MEMORY
;
328 *rtype
= SID_NAME_DOMAIN
;
332 if (strcasecmp_m(username
, state
->domain_name
) == 0) {
333 *authority_name
= talloc_strdup(mem_ctx
,
335 if (*authority_name
== NULL
) {
336 return NT_STATUS_NO_MEMORY
;
338 *sid
= dom_sid_dup(mem_ctx
, state
->domain_sid
);
340 return NT_STATUS_NO_MEMORY
;
342 *rtype
= SID_NAME_DOMAIN
;
347 /* Perhaps this is a well known user? */
348 name
= talloc_asprintf(mem_ctx
, "%s\\%s", NAME_NT_AUTHORITY
, username
);
350 return NT_STATUS_NO_MEMORY
;
352 status
= dcesrv_lsa_lookup_name(ev_ctx
, lp_ctx
, state
, mem_ctx
, name
, authority_name
, sid
, rtype
, rid
);
353 if (NT_STATUS_IS_OK(status
)) {
357 /* Perhaps this is a BUILTIN user? */
358 name
= talloc_asprintf(mem_ctx
, "%s\\%s", NAME_BUILTIN
, username
);
360 return NT_STATUS_NO_MEMORY
;
362 status
= dcesrv_lsa_lookup_name(ev_ctx
, lp_ctx
, state
, mem_ctx
, name
, authority_name
, sid
, rtype
, rid
);
363 if (NT_STATUS_IS_OK(status
)) {
367 /* OK, I give up - perhaps we need to assume the user is in our domain? */
368 name
= talloc_asprintf(mem_ctx
, "%s\\%s", state
->domain_name
, username
);
370 return NT_STATUS_NO_MEMORY
;
372 status
= dcesrv_lsa_lookup_name(ev_ctx
, lp_ctx
, state
, mem_ctx
, name
, authority_name
, sid
, rtype
, rid
);
373 if (NT_STATUS_IS_OK(status
)) {
377 return STATUS_SOME_UNMAPPED
;
378 } else if (strcasecmp_m(domain
, NAME_NT_AUTHORITY
) == 0) {
380 *authority_name
= NAME_NT_AUTHORITY
;
381 *sid
= dom_sid_parse_talloc(mem_ctx
, SID_NT_AUTHORITY
);
383 return NT_STATUS_NO_MEMORY
;
385 *rtype
= SID_NAME_DOMAIN
;
386 dom_sid_split_rid(NULL
, *sid
, NULL
, rid
);
390 /* Look up table of well known names */
391 status
= lookup_well_known_names(mem_ctx
, domain
, username
, authority_name
,
393 if (NT_STATUS_IS_OK(status
)) {
394 dom_sid_split_rid(NULL
, *sid
, NULL
, rid
);
397 } else if (strcasecmp_m(domain
, NAME_BUILTIN
) == 0) {
398 *authority_name
= NAME_BUILTIN
;
399 domain_dn
= state
->builtin_dn
;
400 } else if (strcasecmp_m(domain
, state
->domain_dns
) == 0) {
401 *authority_name
= talloc_strdup(mem_ctx
,
403 if (*authority_name
== NULL
) {
404 return NT_STATUS_NO_MEMORY
;
406 domain_dn
= state
->domain_dn
;
407 } else if (strcasecmp_m(domain
, state
->domain_name
) == 0) {
408 *authority_name
= talloc_strdup(mem_ctx
,
410 if (*authority_name
== NULL
) {
411 return NT_STATUS_NO_MEMORY
;
413 domain_dn
= state
->domain_dn
;
415 /* Not local, need to ask winbind in future */
416 return STATUS_SOME_UNMAPPED
;
419 ret
= gendb_search_dn(state
->sam_ldb
, mem_ctx
, domain_dn
, &res
, attrs
);
421 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
423 domain_sid
= samdb_result_dom_sid(mem_ctx
, res
[0], "objectSid");
424 if (domain_sid
== NULL
) {
425 return NT_STATUS_INVALID_SID
;
430 *rtype
= SID_NAME_DOMAIN
;
435 ret
= gendb_search(state
->sam_ldb
, mem_ctx
, domain_dn
, &res
, attrs
,
436 "(&(sAMAccountName=%s)(objectSid=*))",
437 ldb_binary_encode_string(mem_ctx
, username
));
439 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
442 for (i
=0; i
< ret
; i
++) {
443 *sid
= samdb_result_dom_sid(mem_ctx
, res
[i
], "objectSid");
445 return NT_STATUS_INVALID_SID
;
448 /* Check that this is in the domain */
449 if (!dom_sid_in_domain(domain_sid
, *sid
)) {
453 atype
= ldb_msg_find_attr_as_uint(res
[i
], "sAMAccountType", 0);
455 *rtype
= ds_atype_map(atype
);
456 if (*rtype
== SID_NAME_UNKNOWN
) {
457 return STATUS_SOME_UNMAPPED
;
460 dom_sid_split_rid(NULL
, *sid
, NULL
, rid
);
464 /* need to check for an allocated sid */
466 return NT_STATUS_INVALID_SID
;
471 add to the lsa_RefDomainList for LookupSids and LookupNames
473 static NTSTATUS
dcesrv_lsa_authority_list(struct lsa_policy_state
*state
, TALLOC_CTX
*mem_ctx
,
474 enum lsa_SidType rtype
,
475 const char *authority_name
,
477 struct lsa_RefDomainList
*domains
,
480 struct dom_sid
*authority_sid
;
483 if (rtype
!= SID_NAME_DOMAIN
) {
484 authority_sid
= dom_sid_dup(mem_ctx
, sid
);
485 if (authority_sid
== NULL
) {
486 return NT_STATUS_NO_MEMORY
;
488 authority_sid
->num_auths
--;
493 /* see if we've already done this authority name */
494 for (i
=0;i
<domains
->count
;i
++) {
495 if (strcasecmp_m(authority_name
, domains
->domains
[i
].name
.string
) == 0) {
501 domains
->domains
= talloc_realloc(domains
,
503 struct lsa_DomainInfo
,
505 if (domains
->domains
== NULL
) {
506 return NT_STATUS_NO_MEMORY
;
508 domains
->domains
[i
].name
.string
= authority_name
;
509 domains
->domains
[i
].sid
= authority_sid
;
511 domains
->max_size
= LSA_REF_DOMAIN_LIST_MULTIPLIER
* domains
->count
;
518 lookup a name for 1 SID
520 static NTSTATUS
dcesrv_lsa_lookup_sid(struct lsa_policy_state
*state
, TALLOC_CTX
*mem_ctx
,
521 struct dom_sid
*sid
, const char *sid_str
,
522 const char **authority_name
,
523 const char **name
, enum lsa_SidType
*rtype
)
528 struct ldb_message
**res
;
529 struct ldb_dn
*domain_dn
;
530 const char * const attrs
[] = { "sAMAccountName", "sAMAccountType", "cn", NULL
};
532 status
= lookup_well_known_sids(mem_ctx
, sid_str
, authority_name
, name
, rtype
);
533 if (NT_STATUS_IS_OK(status
)) {
537 if (dom_sid_equal(state
->domain_sid
, sid
)) {
538 *authority_name
= talloc_strdup(mem_ctx
, state
->domain_name
);
539 if (*authority_name
== NULL
) {
540 return NT_STATUS_NO_MEMORY
;
543 *rtype
= SID_NAME_DOMAIN
;
547 if (dom_sid_in_domain(state
->domain_sid
, sid
)) {
548 *authority_name
= talloc_strdup(mem_ctx
, state
->domain_name
);
549 if (*authority_name
== NULL
) {
550 return NT_STATUS_NO_MEMORY
;
552 domain_dn
= state
->domain_dn
;
553 } else if (dom_sid_in_domain(state
->builtin_sid
, sid
)) {
554 *authority_name
= NAME_BUILTIN
;
555 domain_dn
= state
->builtin_dn
;
557 /* Not well known, our domain or built in */
559 /* In future, we must look at SID histories, and at trusted domains via winbind */
561 return NT_STATUS_NOT_FOUND
;
564 /* need to re-add a check for an allocated sid */
566 ret
= gendb_search(state
->sam_ldb
, mem_ctx
, domain_dn
, &res
, attrs
,
567 "objectSid=%s", ldap_encode_ndr_dom_sid(mem_ctx
, sid
));
568 if ((ret
< 0) || (ret
> 1)) {
569 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
572 return NT_STATUS_NOT_FOUND
;
575 *name
= ldb_msg_find_attr_as_string(res
[0], "sAMAccountName", NULL
);
577 *name
= ldb_msg_find_attr_as_string(res
[0], "cn", NULL
);
579 *name
= talloc_strdup(mem_ctx
, sid_str
);
580 NT_STATUS_HAVE_NO_MEMORY(*name
);
584 atype
= ldb_msg_find_attr_as_uint(res
[0], "sAMAccountType", 0);
585 *rtype
= ds_atype_map(atype
);
590 static NTSTATUS
dcesrv_lsa_LookupSids_common(struct dcesrv_call_state
*dce_call
,
592 struct lsa_policy_state
*policy_state
,
593 struct lsa_LookupSids2
*r
)
595 struct lsa_RefDomainList
*domains
= NULL
;
598 *r
->out
.domains
= NULL
;
599 r
->out
.names
->count
= 0;
600 r
->out
.names
->names
= NULL
;
603 if (r
->in
.level
< LSA_LOOKUP_NAMES_ALL
||
604 r
->in
.level
> LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC
) {
605 return NT_STATUS_INVALID_PARAMETER
;
608 /* NOTE: the WSPP test suite tries SIDs with invalid revision numbers,
609 and expects NT_STATUS_INVALID_PARAMETER back - we just treat it as
610 an unknown SID. We could add a SID validator here. (tridge)
614 domains
= talloc_zero(r
->out
.domains
, struct lsa_RefDomainList
);
615 if (domains
== NULL
) {
616 return NT_STATUS_NO_MEMORY
;
618 *r
->out
.domains
= domains
;
620 r
->out
.names
->names
= talloc_array(r
->out
.names
, struct lsa_TranslatedName2
,
621 r
->in
.sids
->num_sids
);
622 if (r
->out
.names
->names
== NULL
) {
623 return NT_STATUS_NO_MEMORY
;
626 for (i
=0;i
<r
->in
.sids
->num_sids
;i
++) {
627 struct dom_sid
*sid
= r
->in
.sids
->sids
[i
].sid
;
628 char *sid_str
= dom_sid_string(mem_ctx
, sid
);
629 const char *name
, *authority_name
;
630 enum lsa_SidType rtype
;
634 r
->out
.names
->count
++;
636 r
->out
.names
->names
[i
].sid_type
= SID_NAME_UNKNOWN
;
637 r
->out
.names
->names
[i
].name
.string
= sid_str
;
638 r
->out
.names
->names
[i
].sid_index
= 0xFFFFFFFF;
639 r
->out
.names
->names
[i
].unknown
= 0;
641 if (sid_str
== NULL
) {
642 r
->out
.names
->names
[i
].name
.string
= "(SIDERROR)";
646 status2
= dcesrv_lsa_lookup_sid(policy_state
, mem_ctx
, sid
, sid_str
,
647 &authority_name
, &name
, &rtype
);
648 if (!NT_STATUS_IS_OK(status2
)) {
652 /* set up the authority table */
653 status2
= dcesrv_lsa_authority_list(policy_state
, mem_ctx
, rtype
,
655 domains
, &sid_index
);
656 if (!NT_STATUS_IS_OK(status2
)) {
660 r
->out
.names
->names
[i
].sid_type
= rtype
;
661 r
->out
.names
->names
[i
].name
.string
= name
;
662 r
->out
.names
->names
[i
].sid_index
= sid_index
;
663 r
->out
.names
->names
[i
].unknown
= 0;
668 if (*r
->out
.count
== 0) {
669 return NT_STATUS_NONE_MAPPED
;
671 if (*r
->out
.count
!= r
->in
.sids
->num_sids
) {
672 return STATUS_SOME_UNMAPPED
;
681 NTSTATUS
dcesrv_lsa_LookupSids2(struct dcesrv_call_state
*dce_call
,
683 struct lsa_LookupSids2
*r
)
685 enum dcerpc_transport_t transport
=
686 dcerpc_binding_get_transport(dce_call
->conn
->endpoint
->ep_description
);
687 struct lsa_policy_state
*policy_state
= NULL
;
688 struct dcesrv_handle
*policy_handle
= NULL
;
690 if (transport
!= NCACN_NP
&& transport
!= NCALRPC
) {
691 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED
);
694 DCESRV_PULL_HANDLE(policy_handle
, r
->in
.handle
, LSA_HANDLE_POLICY
);
696 policy_state
= policy_handle
->data
;
698 return dcesrv_lsa_LookupSids_common(dce_call
,
708 Identical to LookupSids2, but doesn't take a policy handle
711 NTSTATUS
dcesrv_lsa_LookupSids3(struct dcesrv_call_state
*dce_call
,
713 struct lsa_LookupSids3
*r
)
715 enum dcerpc_transport_t transport
=
716 dcerpc_binding_get_transport(dce_call
->conn
->endpoint
->ep_description
);
717 const struct dcesrv_auth
*auth
= &dce_call
->conn
->auth_state
;
718 struct lsa_policy_state
*policy_state
;
719 struct lsa_LookupSids2 q
;
722 if (transport
!= NCACN_IP_TCP
) {
723 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED
);
727 * We don't have policy handles on this call. So this must be restricted
728 * to crypto connections only.
730 if (auth
->auth_type
!= DCERPC_AUTH_TYPE_SCHANNEL
||
731 auth
->auth_level
< DCERPC_AUTH_LEVEL_INTEGRITY
) {
732 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED
);
735 *r
->out
.domains
= NULL
;
736 r
->out
.names
->count
= 0;
737 r
->out
.names
->names
= NULL
;
740 status
= dcesrv_lsa_get_policy_state(dce_call
, mem_ctx
,
741 0, /* we skip access checks */
743 if (!NT_STATUS_IS_OK(status
)) {
750 q
.in
.sids
= r
->in
.sids
;
751 q
.in
.names
= r
->in
.names
;
752 q
.in
.level
= r
->in
.level
;
753 q
.in
.count
= r
->in
.count
;
754 q
.in
.lookup_options
= r
->in
.lookup_options
;
755 q
.in
.client_revision
= r
->in
.client_revision
;
756 q
.out
.count
= r
->out
.count
;
757 q
.out
.names
= r
->out
.names
;
758 q
.out
.domains
= r
->out
.domains
;
760 status
= dcesrv_lsa_LookupSids_common(dce_call
,
765 talloc_free(policy_state
);
767 r
->out
.count
= q
.out
.count
;
768 r
->out
.names
= q
.out
.names
;
769 r
->out
.domains
= q
.out
.domains
;
778 NTSTATUS
dcesrv_lsa_LookupSids(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
779 struct lsa_LookupSids
*r
)
781 enum dcerpc_transport_t transport
=
782 dcerpc_binding_get_transport(dce_call
->conn
->endpoint
->ep_description
);
783 struct lsa_LookupSids2 r2
;
787 if (transport
!= NCACN_NP
&& transport
!= NCALRPC
) {
788 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED
);
791 *r
->out
.domains
= NULL
;
792 r
->out
.names
->count
= 0;
793 r
->out
.names
->names
= NULL
;
796 r
->out
.names
->names
= talloc_zero_array(r
->out
.names
,
797 struct lsa_TranslatedName
,
798 r
->in
.sids
->num_sids
);
799 if (r
->out
.names
->names
== NULL
) {
800 return NT_STATUS_NO_MEMORY
;
805 r2
.in
.handle
= r
->in
.handle
;
806 r2
.in
.sids
= r
->in
.sids
;
807 r2
.in
.names
= talloc_zero(mem_ctx
, struct lsa_TransNameArray2
);
808 if (r2
.in
.names
== NULL
) {
809 return NT_STATUS_NO_MEMORY
;
811 r2
.in
.level
= r
->in
.level
;
812 r2
.in
.count
= r
->in
.count
;
813 r2
.in
.lookup_options
= LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES
;
814 r2
.in
.client_revision
= LSA_CLIENT_REVISION_1
;
815 r2
.out
.count
= r
->out
.count
;
816 r2
.out
.names
= talloc_zero(mem_ctx
, struct lsa_TransNameArray2
);
817 if (r2
.out
.names
== NULL
) {
818 return NT_STATUS_NO_MEMORY
;
820 r2
.out
.domains
= r
->out
.domains
;
822 status
= dcesrv_lsa_LookupSids2(dce_call
, mem_ctx
, &r2
);
823 /* we deliberately don't check for error from the above,
824 as even on error we are supposed to return the names */
826 SMB_ASSERT(r2
.out
.names
->count
<= r
->in
.sids
->num_sids
);
827 for (i
=0;i
<r2
.out
.names
->count
;i
++) {
828 r
->out
.names
->names
[i
].sid_type
= r2
.out
.names
->names
[i
].sid_type
;
829 r
->out
.names
->names
[i
].name
.string
= r2
.out
.names
->names
[i
].name
.string
;
830 r
->out
.names
->names
[i
].sid_index
= r2
.out
.names
->names
[i
].sid_index
;
832 r
->out
.names
->count
= r2
.out
.names
->count
;
837 static NTSTATUS
dcesrv_lsa_LookupNames_common(struct dcesrv_call_state
*dce_call
,
839 struct lsa_policy_state
*policy_state
,
840 struct lsa_LookupNames3
*r
)
842 struct loadparm_context
*lp_ctx
= dce_call
->conn
->dce_ctx
->lp_ctx
;
843 struct lsa_RefDomainList
*domains
;
846 *r
->out
.domains
= NULL
;
847 r
->out
.sids
->count
= 0;
848 r
->out
.sids
->sids
= NULL
;
851 if (r
->in
.level
< LSA_LOOKUP_NAMES_ALL
||
852 r
->in
.level
> LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC
) {
853 return NT_STATUS_INVALID_PARAMETER
;
856 domains
= talloc_zero(r
->out
.domains
, struct lsa_RefDomainList
);
857 if (domains
== NULL
) {
858 return NT_STATUS_NO_MEMORY
;
860 *r
->out
.domains
= domains
;
862 r
->out
.sids
->sids
= talloc_array(r
->out
.sids
, struct lsa_TranslatedSid3
,
864 if (r
->out
.sids
->sids
== NULL
) {
865 return NT_STATUS_NO_MEMORY
;
868 for (i
=0;i
<r
->in
.num_names
;i
++) {
869 const char *name
= r
->in
.names
[i
].string
;
870 const char *authority_name
;
872 uint32_t sid_index
, rid
;
873 enum lsa_SidType rtype
;
876 r
->out
.sids
->count
++;
878 r
->out
.sids
->sids
[i
].sid_type
= SID_NAME_UNKNOWN
;
879 r
->out
.sids
->sids
[i
].sid
= NULL
;
880 r
->out
.sids
->sids
[i
].sid_index
= 0xFFFFFFFF;
881 r
->out
.sids
->sids
[i
].flags
= 0;
883 status2
= dcesrv_lsa_lookup_name(dce_call
->event_ctx
, lp_ctx
, policy_state
, mem_ctx
, name
,
884 &authority_name
, &sid
, &rtype
, &rid
);
885 if (!NT_STATUS_IS_OK(status2
) || sid
->num_auths
== 0) {
889 status2
= dcesrv_lsa_authority_list(policy_state
, mem_ctx
, rtype
, authority_name
,
890 sid
, domains
, &sid_index
);
891 if (!NT_STATUS_IS_OK(status2
)) {
895 r
->out
.sids
->sids
[i
].sid_type
= rtype
;
896 r
->out
.sids
->sids
[i
].sid
= sid
;
897 r
->out
.sids
->sids
[i
].sid_index
= sid_index
;
898 r
->out
.sids
->sids
[i
].flags
= 0;
903 if (*r
->out
.count
== 0) {
904 return NT_STATUS_NONE_MAPPED
;
906 if (*r
->out
.count
!= r
->in
.num_names
) {
907 return STATUS_SOME_UNMAPPED
;
916 NTSTATUS
dcesrv_lsa_LookupNames3(struct dcesrv_call_state
*dce_call
,
918 struct lsa_LookupNames3
*r
)
920 enum dcerpc_transport_t transport
=
921 dcerpc_binding_get_transport(dce_call
->conn
->endpoint
->ep_description
);
922 struct lsa_policy_state
*policy_state
;
923 struct dcesrv_handle
*policy_handle
;
925 if (transport
!= NCACN_NP
&& transport
!= NCALRPC
) {
926 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED
);
929 DCESRV_PULL_HANDLE(policy_handle
, r
->in
.handle
, LSA_HANDLE_POLICY
);
931 policy_state
= policy_handle
->data
;
933 return dcesrv_lsa_LookupNames_common(dce_call
,
942 Identical to LookupNames3, but doesn't take a policy handle
945 NTSTATUS
dcesrv_lsa_LookupNames4(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
946 struct lsa_LookupNames4
*r
)
948 enum dcerpc_transport_t transport
=
949 dcerpc_binding_get_transport(dce_call
->conn
->endpoint
->ep_description
);
950 const struct dcesrv_auth
*auth
= &dce_call
->conn
->auth_state
;
951 struct lsa_policy_state
*policy_state
;
952 struct lsa_LookupNames3 q
;
955 if (transport
!= NCACN_IP_TCP
) {
956 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED
);
960 * We don't have policy handles on this call. So this must be restricted
961 * to crypto connections only.
963 if (auth
->auth_type
!= DCERPC_AUTH_TYPE_SCHANNEL
||
964 auth
->auth_level
< DCERPC_AUTH_LEVEL_INTEGRITY
) {
965 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED
);
968 *r
->out
.domains
= NULL
;
969 r
->out
.sids
->count
= 0;
970 r
->out
.sids
->sids
= NULL
;
973 status
= dcesrv_lsa_get_policy_state(dce_call
, mem_ctx
,
974 0, /* we skip access checks */
976 if (!NT_STATUS_IS_OK(status
)) {
983 q
.in
.num_names
= r
->in
.num_names
;
984 q
.in
.names
= r
->in
.names
;
985 q
.in
.level
= r
->in
.level
;
986 q
.in
.sids
= r
->in
.sids
;
987 q
.in
.count
= r
->in
.count
;
988 q
.in
.lookup_options
= r
->in
.lookup_options
;
989 q
.in
.client_revision
= r
->in
.client_revision
;
991 q
.out
.count
= r
->out
.count
;
992 q
.out
.sids
= r
->out
.sids
;
993 q
.out
.domains
= r
->out
.domains
;
995 status
= dcesrv_lsa_LookupNames_common(dce_call
,
1000 talloc_free(policy_state
);
1002 r
->out
.count
= q
.out
.count
;
1003 r
->out
.sids
= q
.out
.sids
;
1004 r
->out
.domains
= q
.out
.domains
;
1012 NTSTATUS
dcesrv_lsa_LookupNames2(struct dcesrv_call_state
*dce_call
,
1013 TALLOC_CTX
*mem_ctx
,
1014 struct lsa_LookupNames2
*r
)
1016 enum dcerpc_transport_t transport
=
1017 dcerpc_binding_get_transport(dce_call
->conn
->endpoint
->ep_description
);
1018 struct lsa_policy_state
*state
;
1019 struct dcesrv_handle
*h
;
1021 struct loadparm_context
*lp_ctx
= dce_call
->conn
->dce_ctx
->lp_ctx
;
1022 struct lsa_RefDomainList
*domains
;
1024 if (transport
!= NCACN_NP
&& transport
!= NCALRPC
) {
1025 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED
);
1028 DCESRV_PULL_HANDLE(h
, r
->in
.handle
, LSA_HANDLE_POLICY
);
1030 *r
->out
.domains
= NULL
;
1031 r
->out
.sids
->count
= 0;
1032 r
->out
.sids
->sids
= NULL
;
1035 if (r
->in
.level
< LSA_LOOKUP_NAMES_ALL
||
1036 r
->in
.level
> LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC
) {
1037 return NT_STATUS_INVALID_PARAMETER
;
1042 domains
= talloc_zero(r
->out
.domains
, struct lsa_RefDomainList
);
1043 if (domains
== NULL
) {
1044 return NT_STATUS_NO_MEMORY
;
1046 *r
->out
.domains
= domains
;
1048 r
->out
.sids
->sids
= talloc_array(r
->out
.sids
, struct lsa_TranslatedSid2
,
1050 if (r
->out
.sids
->sids
== NULL
) {
1051 return NT_STATUS_NO_MEMORY
;
1054 for (i
=0;i
<r
->in
.num_names
;i
++) {
1055 const char *name
= r
->in
.names
[i
].string
;
1056 const char *authority_name
;
1057 struct dom_sid
*sid
;
1058 uint32_t sid_index
, rid
=0;
1059 enum lsa_SidType rtype
;
1062 r
->out
.sids
->count
++;
1064 r
->out
.sids
->sids
[i
].sid_type
= SID_NAME_UNKNOWN
;
1065 /* MS-LSAT 3.1.4.7 - rid zero is considered equivalent
1066 to sid NULL - so we should return 0 rid for
1068 r
->out
.sids
->sids
[i
].rid
= 0;
1069 r
->out
.sids
->sids
[i
].sid_index
= 0xFFFFFFFF;
1070 r
->out
.sids
->sids
[i
].unknown
= 0;
1072 status2
= dcesrv_lsa_lookup_name(dce_call
->event_ctx
, lp_ctx
, state
, mem_ctx
, name
,
1073 &authority_name
, &sid
, &rtype
, &rid
);
1074 if (!NT_STATUS_IS_OK(status2
)) {
1078 status2
= dcesrv_lsa_authority_list(state
, mem_ctx
, rtype
, authority_name
,
1079 sid
, domains
, &sid_index
);
1080 if (!NT_STATUS_IS_OK(status2
)) {
1084 r
->out
.sids
->sids
[i
].sid_type
= rtype
;
1085 r
->out
.sids
->sids
[i
].rid
= rid
;
1086 r
->out
.sids
->sids
[i
].sid_index
= sid_index
;
1087 r
->out
.sids
->sids
[i
].unknown
= 0;
1092 if (*r
->out
.count
== 0) {
1093 return NT_STATUS_NONE_MAPPED
;
1095 if (*r
->out
.count
!= r
->in
.num_names
) {
1096 return STATUS_SOME_UNMAPPED
;
1099 return NT_STATUS_OK
;
1105 NTSTATUS
dcesrv_lsa_LookupNames(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1106 struct lsa_LookupNames
*r
)
1108 enum dcerpc_transport_t transport
=
1109 dcerpc_binding_get_transport(dce_call
->conn
->endpoint
->ep_description
);
1110 struct lsa_LookupNames2 r2
;
1114 if (transport
!= NCACN_NP
&& transport
!= NCALRPC
) {
1115 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED
);
1118 *r
->out
.domains
= NULL
;
1119 r
->out
.sids
->count
= 0;
1120 r
->out
.sids
->sids
= NULL
;
1123 r
->out
.sids
->sids
= talloc_zero_array(r
->out
.sids
,
1124 struct lsa_TranslatedSid
,
1126 if (r
->out
.sids
->sids
== NULL
) {
1127 return NT_STATUS_NO_MEMORY
;
1132 r2
.in
.handle
= r
->in
.handle
;
1133 r2
.in
.num_names
= r
->in
.num_names
;
1134 r2
.in
.names
= r
->in
.names
;
1135 r2
.in
.sids
= talloc_zero(mem_ctx
, struct lsa_TransSidArray2
);
1136 if (r2
.in
.sids
== NULL
) {
1137 return NT_STATUS_NO_MEMORY
;
1139 r2
.in
.level
= r
->in
.level
;
1140 r2
.in
.count
= r
->in
.count
;
1141 r2
.in
.lookup_options
= LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES
;
1142 r2
.in
.client_revision
= LSA_CLIENT_REVISION_1
;
1143 r2
.out
.count
= r
->out
.count
;
1144 r2
.out
.sids
= talloc_zero(mem_ctx
, struct lsa_TransSidArray2
);
1145 if (r2
.out
.sids
== NULL
) {
1146 return NT_STATUS_NO_MEMORY
;
1148 r2
.out
.domains
= r
->out
.domains
;
1150 status
= dcesrv_lsa_LookupNames2(dce_call
, mem_ctx
, &r2
);
1152 SMB_ASSERT(r2
.out
.sids
->count
<= r
->in
.num_names
);
1153 for (i
=0;i
<r2
.out
.sids
->count
;i
++) {
1154 r
->out
.sids
->sids
[i
].sid_type
= r2
.out
.sids
->sids
[i
].sid_type
;
1155 r
->out
.sids
->sids
[i
].rid
= r2
.out
.sids
->sids
[i
].rid
;
1156 r
->out
.sids
->sids
[i
].sid_index
= r2
.out
.sids
->sids
[i
].sid_index
;
1158 r
->out
.sids
->count
= r2
.out
.sids
->count
;