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 struct dcesrv_lsa_LookupSids_base_state
{
591 struct dcesrv_call_state
*dce_call
;
595 struct lsa_policy_state
*policy_state
;
597 struct lsa_LookupSids3 r
;
600 struct lsa_LookupSids
*l
;
601 struct lsa_LookupSids2
*l2
;
602 struct lsa_LookupSids3
*l3
;
606 static NTSTATUS
dcesrv_lsa_LookupSids_base_call(struct dcesrv_lsa_LookupSids_base_state
*state
)
608 struct lsa_policy_state
*policy_state
= state
->policy_state
;
609 TALLOC_CTX
*mem_ctx
= state
->mem_ctx
;
610 struct lsa_LookupSids3
*r
= &state
->r
;
611 struct lsa_RefDomainList
*domains
= NULL
;
614 *r
->out
.domains
= NULL
;
615 r
->out
.names
->count
= 0;
616 r
->out
.names
->names
= NULL
;
619 if (r
->in
.level
< LSA_LOOKUP_NAMES_ALL
||
620 r
->in
.level
> LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC
) {
621 return NT_STATUS_INVALID_PARAMETER
;
624 /* NOTE: the WSPP test suite tries SIDs with invalid revision numbers,
625 and expects NT_STATUS_INVALID_PARAMETER back - we just treat it as
626 an unknown SID. We could add a SID validator here. (tridge)
630 domains
= talloc_zero(r
->out
.domains
, struct lsa_RefDomainList
);
631 if (domains
== NULL
) {
632 return NT_STATUS_NO_MEMORY
;
634 *r
->out
.domains
= domains
;
636 r
->out
.names
->names
= talloc_array(r
->out
.names
, struct lsa_TranslatedName2
,
637 r
->in
.sids
->num_sids
);
638 if (r
->out
.names
->names
== NULL
) {
639 return NT_STATUS_NO_MEMORY
;
642 for (i
=0;i
<r
->in
.sids
->num_sids
;i
++) {
643 struct dom_sid
*sid
= r
->in
.sids
->sids
[i
].sid
;
644 char *sid_str
= dom_sid_string(mem_ctx
, sid
);
645 const char *name
, *authority_name
;
646 enum lsa_SidType rtype
;
650 r
->out
.names
->count
++;
652 r
->out
.names
->names
[i
].sid_type
= SID_NAME_UNKNOWN
;
653 r
->out
.names
->names
[i
].name
.string
= sid_str
;
654 r
->out
.names
->names
[i
].sid_index
= 0xFFFFFFFF;
655 r
->out
.names
->names
[i
].unknown
= 0;
657 if (sid_str
== NULL
) {
658 r
->out
.names
->names
[i
].name
.string
= "(SIDERROR)";
662 status2
= dcesrv_lsa_lookup_sid(policy_state
, mem_ctx
, sid
, sid_str
,
663 &authority_name
, &name
, &rtype
);
664 if (!NT_STATUS_IS_OK(status2
)) {
668 /* set up the authority table */
669 status2
= dcesrv_lsa_authority_list(policy_state
, mem_ctx
, rtype
,
671 domains
, &sid_index
);
672 if (!NT_STATUS_IS_OK(status2
)) {
676 r
->out
.names
->names
[i
].sid_type
= rtype
;
677 r
->out
.names
->names
[i
].name
.string
= name
;
678 r
->out
.names
->names
[i
].sid_index
= sid_index
;
679 r
->out
.names
->names
[i
].unknown
= 0;
684 if (*r
->out
.count
== 0) {
685 return NT_STATUS_NONE_MAPPED
;
687 if (*r
->out
.count
!= r
->in
.sids
->num_sids
) {
688 return STATUS_SOME_UNMAPPED
;
694 static void dcesrv_lsa_LookupSids_base_map(
695 struct dcesrv_lsa_LookupSids_base_state
*state
)
697 if (state
->_r
.l3
!= NULL
) {
698 struct lsa_LookupSids3
*r
= state
->_r
.l3
;
700 r
->out
.result
= state
->r
.out
.result
;
704 if (state
->_r
.l2
!= NULL
) {
705 struct lsa_LookupSids2
*r
= state
->_r
.l2
;
707 r
->out
.result
= state
->r
.out
.result
;
711 if (state
->_r
.l
!= NULL
) {
712 struct lsa_LookupSids
*r
= state
->_r
.l
;
715 r
->out
.result
= state
->r
.out
.result
;
717 SMB_ASSERT(state
->r
.out
.names
->count
<= r
->in
.sids
->num_sids
);
718 for (i
= 0; i
< state
->r
.out
.names
->count
; i
++) {
719 struct lsa_TranslatedName2
*n2
=
720 &state
->r
.out
.names
->names
[i
];
721 struct lsa_TranslatedName
*n
=
722 &r
->out
.names
->names
[i
];
724 n
->sid_type
= n2
->sid_type
;
726 n
->sid_index
= n2
->sid_index
;
728 r
->out
.names
->count
= state
->r
.out
.names
->count
;
736 NTSTATUS
dcesrv_lsa_LookupSids2(struct dcesrv_call_state
*dce_call
,
738 struct lsa_LookupSids2
*r
)
740 enum dcerpc_transport_t transport
=
741 dcerpc_binding_get_transport(dce_call
->conn
->endpoint
->ep_description
);
742 struct dcesrv_lsa_LookupSids_base_state
*state
= NULL
;
743 struct dcesrv_handle
*policy_handle
= NULL
;
746 if (transport
!= NCACN_NP
&& transport
!= NCALRPC
) {
747 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED
);
750 DCESRV_PULL_HANDLE(policy_handle
, r
->in
.handle
, LSA_HANDLE_POLICY
);
752 *r
->out
.domains
= NULL
;
753 r
->out
.names
->count
= 0;
754 r
->out
.names
->names
= NULL
;
757 state
= talloc_zero(mem_ctx
, struct dcesrv_lsa_LookupSids_base_state
);
759 return NT_STATUS_NO_MEMORY
;
762 state
->dce_call
= dce_call
;
763 state
->mem_ctx
= mem_ctx
;
765 state
->policy_state
= policy_handle
->data
;
767 state
->r
.in
.sids
= r
->in
.sids
;
768 state
->r
.in
.level
= r
->in
.level
;
769 state
->r
.in
.lookup_options
= r
->in
.lookup_options
;
770 state
->r
.in
.client_revision
= r
->in
.client_revision
;
771 state
->r
.in
.names
= r
->in
.names
;
772 state
->r
.in
.count
= r
->in
.count
;
773 state
->r
.out
.domains
= r
->out
.domains
;
774 state
->r
.out
.names
= r
->out
.names
;
775 state
->r
.out
.count
= r
->out
.count
;
779 status
= dcesrv_lsa_LookupSids_base_call(state
);
781 if (dce_call
->state_flags
& DCESRV_CALL_STATE_FLAG_ASYNC
) {
785 state
->r
.out
.result
= status
;
786 dcesrv_lsa_LookupSids_base_map(state
);
795 Identical to LookupSids2, but doesn't take a policy handle
798 NTSTATUS
dcesrv_lsa_LookupSids3(struct dcesrv_call_state
*dce_call
,
800 struct lsa_LookupSids3
*r
)
802 enum dcerpc_transport_t transport
=
803 dcerpc_binding_get_transport(dce_call
->conn
->endpoint
->ep_description
);
804 const struct dcesrv_auth
*auth
= &dce_call
->conn
->auth_state
;
805 struct dcesrv_lsa_LookupSids_base_state
*state
= NULL
;
808 if (transport
!= NCACN_IP_TCP
) {
809 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED
);
813 * We don't have policy handles on this call. So this must be restricted
814 * to crypto connections only.
816 if (auth
->auth_type
!= DCERPC_AUTH_TYPE_SCHANNEL
||
817 auth
->auth_level
< DCERPC_AUTH_LEVEL_INTEGRITY
) {
818 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED
);
821 *r
->out
.domains
= NULL
;
822 r
->out
.names
->count
= 0;
823 r
->out
.names
->names
= NULL
;
826 state
= talloc_zero(mem_ctx
, struct dcesrv_lsa_LookupSids_base_state
);
828 return NT_STATUS_NO_MEMORY
;
831 state
->dce_call
= dce_call
;
832 state
->mem_ctx
= mem_ctx
;
834 status
= dcesrv_lsa_get_policy_state(state
->dce_call
, mem_ctx
,
835 0, /* we skip access checks */
836 &state
->policy_state
);
837 if (!NT_STATUS_IS_OK(status
)) {
841 state
->r
.in
.sids
= r
->in
.sids
;
842 state
->r
.in
.level
= r
->in
.level
;
843 state
->r
.in
.lookup_options
= r
->in
.lookup_options
;
844 state
->r
.in
.client_revision
= r
->in
.client_revision
;
845 state
->r
.in
.names
= r
->in
.names
;
846 state
->r
.in
.count
= r
->in
.count
;
847 state
->r
.out
.domains
= r
->out
.domains
;
848 state
->r
.out
.names
= r
->out
.names
;
849 state
->r
.out
.count
= r
->out
.count
;
853 status
= dcesrv_lsa_LookupSids_base_call(state
);
855 if (dce_call
->state_flags
& DCESRV_CALL_STATE_FLAG_ASYNC
) {
859 state
->r
.out
.result
= status
;
860 dcesrv_lsa_LookupSids_base_map(state
);
869 NTSTATUS
dcesrv_lsa_LookupSids(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
870 struct lsa_LookupSids
*r
)
872 enum dcerpc_transport_t transport
=
873 dcerpc_binding_get_transport(dce_call
->conn
->endpoint
->ep_description
);
874 struct dcesrv_lsa_LookupSids_base_state
*state
= NULL
;
875 struct dcesrv_handle
*policy_handle
= NULL
;
878 if (transport
!= NCACN_NP
&& transport
!= NCALRPC
) {
879 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED
);
882 DCESRV_PULL_HANDLE(policy_handle
, r
->in
.handle
, LSA_HANDLE_POLICY
);
884 *r
->out
.domains
= NULL
;
885 r
->out
.names
->count
= 0;
886 r
->out
.names
->names
= NULL
;
889 r
->out
.names
->names
= talloc_zero_array(r
->out
.names
,
890 struct lsa_TranslatedName
,
891 r
->in
.sids
->num_sids
);
892 if (r
->out
.names
->names
== NULL
) {
893 return NT_STATUS_NO_MEMORY
;
896 state
= talloc_zero(mem_ctx
, struct dcesrv_lsa_LookupSids_base_state
);
898 return NT_STATUS_NO_MEMORY
;
901 state
->dce_call
= dce_call
;
902 state
->mem_ctx
= mem_ctx
;
904 state
->policy_state
= policy_handle
->data
;
906 state
->r
.in
.sids
= r
->in
.sids
;
907 state
->r
.in
.level
= r
->in
.level
;
908 state
->r
.in
.lookup_options
= LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES
;
909 state
->r
.in
.client_revision
= LSA_CLIENT_REVISION_1
;
910 state
->r
.in
.names
= talloc_zero(state
, struct lsa_TransNameArray2
);
911 if (state
->r
.in
.names
== NULL
) {
912 return NT_STATUS_NO_MEMORY
;
914 state
->r
.in
.count
= r
->in
.count
;
915 state
->r
.out
.domains
= r
->out
.domains
;
916 state
->r
.out
.names
= talloc_zero(state
, struct lsa_TransNameArray2
);
917 if (state
->r
.out
.names
== NULL
) {
918 return NT_STATUS_NO_MEMORY
;
920 state
->r
.out
.count
= r
->out
.count
;
924 status
= dcesrv_lsa_LookupSids_base_call(state
);
926 if (dce_call
->state_flags
& DCESRV_CALL_STATE_FLAG_ASYNC
) {
930 state
->r
.out
.result
= status
;
931 dcesrv_lsa_LookupSids_base_map(state
);
936 static NTSTATUS
dcesrv_lsa_LookupNames_common(struct dcesrv_call_state
*dce_call
,
938 struct lsa_policy_state
*policy_state
,
939 struct lsa_LookupNames3
*r
)
941 struct loadparm_context
*lp_ctx
= dce_call
->conn
->dce_ctx
->lp_ctx
;
942 struct lsa_RefDomainList
*domains
;
945 *r
->out
.domains
= NULL
;
946 r
->out
.sids
->count
= 0;
947 r
->out
.sids
->sids
= NULL
;
950 if (r
->in
.level
< LSA_LOOKUP_NAMES_ALL
||
951 r
->in
.level
> LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC
) {
952 return NT_STATUS_INVALID_PARAMETER
;
955 domains
= talloc_zero(r
->out
.domains
, struct lsa_RefDomainList
);
956 if (domains
== NULL
) {
957 return NT_STATUS_NO_MEMORY
;
959 *r
->out
.domains
= domains
;
961 r
->out
.sids
->sids
= talloc_array(r
->out
.sids
, struct lsa_TranslatedSid3
,
963 if (r
->out
.sids
->sids
== NULL
) {
964 return NT_STATUS_NO_MEMORY
;
967 for (i
=0;i
<r
->in
.num_names
;i
++) {
968 const char *name
= r
->in
.names
[i
].string
;
969 const char *authority_name
;
971 uint32_t sid_index
, rid
;
972 enum lsa_SidType rtype
;
975 r
->out
.sids
->count
++;
977 r
->out
.sids
->sids
[i
].sid_type
= SID_NAME_UNKNOWN
;
978 r
->out
.sids
->sids
[i
].sid
= NULL
;
979 r
->out
.sids
->sids
[i
].sid_index
= 0xFFFFFFFF;
980 r
->out
.sids
->sids
[i
].flags
= 0;
982 status2
= dcesrv_lsa_lookup_name(dce_call
->event_ctx
, lp_ctx
, policy_state
, mem_ctx
, name
,
983 &authority_name
, &sid
, &rtype
, &rid
);
984 if (!NT_STATUS_IS_OK(status2
) || sid
->num_auths
== 0) {
988 status2
= dcesrv_lsa_authority_list(policy_state
, mem_ctx
, rtype
, authority_name
,
989 sid
, domains
, &sid_index
);
990 if (!NT_STATUS_IS_OK(status2
)) {
994 r
->out
.sids
->sids
[i
].sid_type
= rtype
;
995 r
->out
.sids
->sids
[i
].sid
= sid
;
996 r
->out
.sids
->sids
[i
].sid_index
= sid_index
;
997 r
->out
.sids
->sids
[i
].flags
= 0;
1002 if (*r
->out
.count
== 0) {
1003 return NT_STATUS_NONE_MAPPED
;
1005 if (*r
->out
.count
!= r
->in
.num_names
) {
1006 return STATUS_SOME_UNMAPPED
;
1009 return NT_STATUS_OK
;
1015 NTSTATUS
dcesrv_lsa_LookupNames3(struct dcesrv_call_state
*dce_call
,
1016 TALLOC_CTX
*mem_ctx
,
1017 struct lsa_LookupNames3
*r
)
1019 enum dcerpc_transport_t transport
=
1020 dcerpc_binding_get_transport(dce_call
->conn
->endpoint
->ep_description
);
1021 struct lsa_policy_state
*policy_state
;
1022 struct dcesrv_handle
*policy_handle
;
1024 if (transport
!= NCACN_NP
&& transport
!= NCALRPC
) {
1025 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED
);
1028 DCESRV_PULL_HANDLE(policy_handle
, r
->in
.handle
, LSA_HANDLE_POLICY
);
1030 policy_state
= policy_handle
->data
;
1032 return dcesrv_lsa_LookupNames_common(dce_call
,
1041 Identical to LookupNames3, but doesn't take a policy handle
1044 NTSTATUS
dcesrv_lsa_LookupNames4(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1045 struct lsa_LookupNames4
*r
)
1047 enum dcerpc_transport_t transport
=
1048 dcerpc_binding_get_transport(dce_call
->conn
->endpoint
->ep_description
);
1049 const struct dcesrv_auth
*auth
= &dce_call
->conn
->auth_state
;
1050 struct lsa_policy_state
*policy_state
;
1051 struct lsa_LookupNames3 q
;
1054 if (transport
!= NCACN_IP_TCP
) {
1055 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED
);
1059 * We don't have policy handles on this call. So this must be restricted
1060 * to crypto connections only.
1062 if (auth
->auth_type
!= DCERPC_AUTH_TYPE_SCHANNEL
||
1063 auth
->auth_level
< DCERPC_AUTH_LEVEL_INTEGRITY
) {
1064 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED
);
1067 *r
->out
.domains
= NULL
;
1068 r
->out
.sids
->count
= 0;
1069 r
->out
.sids
->sids
= NULL
;
1072 status
= dcesrv_lsa_get_policy_state(dce_call
, mem_ctx
,
1073 0, /* we skip access checks */
1075 if (!NT_STATUS_IS_OK(status
)) {
1082 q
.in
.num_names
= r
->in
.num_names
;
1083 q
.in
.names
= r
->in
.names
;
1084 q
.in
.level
= r
->in
.level
;
1085 q
.in
.sids
= r
->in
.sids
;
1086 q
.in
.count
= r
->in
.count
;
1087 q
.in
.lookup_options
= r
->in
.lookup_options
;
1088 q
.in
.client_revision
= r
->in
.client_revision
;
1090 q
.out
.count
= r
->out
.count
;
1091 q
.out
.sids
= r
->out
.sids
;
1092 q
.out
.domains
= r
->out
.domains
;
1094 status
= dcesrv_lsa_LookupNames_common(dce_call
,
1099 talloc_free(policy_state
);
1101 r
->out
.count
= q
.out
.count
;
1102 r
->out
.sids
= q
.out
.sids
;
1103 r
->out
.domains
= q
.out
.domains
;
1111 NTSTATUS
dcesrv_lsa_LookupNames2(struct dcesrv_call_state
*dce_call
,
1112 TALLOC_CTX
*mem_ctx
,
1113 struct lsa_LookupNames2
*r
)
1115 enum dcerpc_transport_t transport
=
1116 dcerpc_binding_get_transport(dce_call
->conn
->endpoint
->ep_description
);
1117 struct lsa_policy_state
*policy_state
= NULL
;
1118 struct dcesrv_handle
*policy_handle
= NULL
;
1119 struct lsa_LookupNames3 r2
;
1123 if (transport
!= NCACN_NP
&& transport
!= NCALRPC
) {
1124 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED
);
1127 DCESRV_PULL_HANDLE(policy_handle
, r
->in
.handle
, LSA_HANDLE_POLICY
);
1129 policy_state
= policy_handle
->data
;
1131 *r
->out
.domains
= NULL
;
1132 r
->out
.sids
->count
= 0;
1133 r
->out
.sids
->sids
= NULL
;
1136 r
->out
.sids
->sids
= talloc_zero_array(r
->out
.sids
,
1137 struct lsa_TranslatedSid2
,
1139 if (r
->out
.sids
->sids
== NULL
) {
1140 return NT_STATUS_NO_MEMORY
;
1145 r2
.in
.handle
= r
->in
.handle
;
1146 r2
.in
.num_names
= r
->in
.num_names
;
1147 r2
.in
.names
= r
->in
.names
;
1148 r2
.in
.sids
= talloc_zero(mem_ctx
, struct lsa_TransSidArray3
);
1149 if (r2
.in
.sids
== NULL
) {
1150 return NT_STATUS_NO_MEMORY
;
1152 r2
.in
.level
= r
->in
.level
;
1153 r2
.in
.count
= r
->in
.count
;
1157 * The LookupOptions and ClientRevision parameters MUST be ignored.
1158 * Message processing MUST happen as if LookupOptions is set to
1159 * 0x00000000 and ClientRevision is set to 0x00000002.
1161 r2
.in
.lookup_options
= LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES
;
1162 r2
.in
.client_revision
= LSA_CLIENT_REVISION_2
;
1163 r2
.out
.count
= r
->out
.count
;
1164 r2
.out
.sids
= talloc_zero(mem_ctx
, struct lsa_TransSidArray3
);
1165 if (r2
.out
.sids
== NULL
) {
1166 return NT_STATUS_NO_MEMORY
;
1168 r2
.out
.domains
= r
->out
.domains
;
1170 status
= dcesrv_lsa_LookupNames_common(dce_call
,
1175 SMB_ASSERT(r2
.out
.sids
->count
<= r
->in
.num_names
);
1176 for (i
=0;i
<r2
.out
.sids
->count
;i
++) {
1177 struct lsa_TranslatedSid3
*s3
=
1178 &r2
.out
.sids
->sids
[i
];
1179 struct lsa_TranslatedSid2
*s2
=
1180 &r
->out
.sids
->sids
[i
];
1182 s2
->sid_type
= s3
->sid_type
;
1183 if (s3
->sid_type
== SID_NAME_DOMAIN
) {
1184 s2
->rid
= UINT32_MAX
;
1185 } else if (s3
->flags
& 0x00000004) {
1186 s2
->rid
= UINT32_MAX
;
1187 } else if (s3
->sid
== NULL
) {
1189 * MS-LSAT 3.1.4.7 - rid zero is considered
1190 * equivalent to sid NULL - so we should return
1191 * 0 rid for unmapped entries
1196 dom_sid_split_rid(NULL
, s3
->sid
,
1199 s2
->sid_index
= s3
->sid_index
;
1201 r
->out
.sids
->count
= r2
.out
.sids
->count
;
1209 NTSTATUS
dcesrv_lsa_LookupNames(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1210 struct lsa_LookupNames
*r
)
1212 enum dcerpc_transport_t transport
=
1213 dcerpc_binding_get_transport(dce_call
->conn
->endpoint
->ep_description
);
1214 struct lsa_policy_state
*policy_state
= NULL
;
1215 struct dcesrv_handle
*policy_handle
= NULL
;
1216 struct lsa_LookupNames3 r2
;
1220 if (transport
!= NCACN_NP
&& transport
!= NCALRPC
) {
1221 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED
);
1224 DCESRV_PULL_HANDLE(policy_handle
, r
->in
.handle
, LSA_HANDLE_POLICY
);
1226 policy_state
= policy_handle
->data
;
1228 *r
->out
.domains
= NULL
;
1229 r
->out
.sids
->count
= 0;
1230 r
->out
.sids
->sids
= NULL
;
1233 r
->out
.sids
->sids
= talloc_zero_array(r
->out
.sids
,
1234 struct lsa_TranslatedSid
,
1236 if (r
->out
.sids
->sids
== NULL
) {
1237 return NT_STATUS_NO_MEMORY
;
1242 r2
.in
.handle
= r
->in
.handle
;
1243 r2
.in
.num_names
= r
->in
.num_names
;
1244 r2
.in
.names
= r
->in
.names
;
1245 r2
.in
.sids
= talloc_zero(mem_ctx
, struct lsa_TransSidArray3
);
1246 if (r2
.in
.sids
== NULL
) {
1247 return NT_STATUS_NO_MEMORY
;
1249 r2
.in
.level
= r
->in
.level
;
1250 r2
.in
.count
= r
->in
.count
;
1251 r2
.in
.lookup_options
= LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES
;
1252 r2
.in
.client_revision
= LSA_CLIENT_REVISION_1
;
1253 r2
.out
.count
= r
->out
.count
;
1254 r2
.out
.sids
= talloc_zero(mem_ctx
, struct lsa_TransSidArray3
);
1255 if (r2
.out
.sids
== NULL
) {
1256 return NT_STATUS_NO_MEMORY
;
1258 r2
.out
.domains
= r
->out
.domains
;
1260 status
= dcesrv_lsa_LookupNames_common(dce_call
,
1265 SMB_ASSERT(r2
.out
.sids
->count
<= r
->in
.num_names
);
1266 for (i
=0;i
<r2
.out
.sids
->count
;i
++) {
1267 struct lsa_TranslatedSid3
*s3
=
1268 &r2
.out
.sids
->sids
[i
];
1269 struct lsa_TranslatedSid
*s
=
1270 &r
->out
.sids
->sids
[i
];
1272 s
->sid_type
= s3
->sid_type
;
1273 if (s3
->sid_type
== SID_NAME_DOMAIN
) {
1274 s
->rid
= UINT32_MAX
;
1275 } else if (s3
->flags
& 0x00000004) {
1276 s
->rid
= UINT32_MAX
;
1277 } else if (s3
->sid
== NULL
) {
1279 * MS-LSAT 3.1.4.7 - rid zero is considered
1280 * equivalent to sid NULL - so we should return
1281 * 0 rid for unmapped entries
1286 dom_sid_split_rid(NULL
, s3
->sid
,
1289 s
->sid_index
= s3
->sid_index
;
1291 r
->out
.sids
->count
= r2
.out
.sids
->count
;