2007-09-19 16:45:35 +04:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
2000-12-13 15:52:21 +03:00
RPC pipe client
2001-05-07 05:55:08 +04:00
Copyright ( C ) Tim Potter 2000 - 2001 ,
2000-12-13 15:52:21 +03:00
Copyright ( C ) Andrew Tridgell 1992 - 1997 , 2000 ,
2002-05-17 17:49:01 +04:00
Copyright ( C ) Rafal Szczesniak 2002
2005-09-30 21:13:37 +04:00
Copyright ( C ) Jeremy Allison 2005.
2007-09-20 13:15:26 +04:00
Copyright ( C ) Michael Adam 2007.
2008-02-27 21:38:48 +03:00
Copyright ( C ) Guenther Deschner 2008.
2007-09-19 16:45:35 +04:00
2000-12-13 15:52:21 +03:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
2007-07-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
2000-12-13 15:52:21 +03:00
( at your option ) any later version .
2007-09-19 16:45:35 +04:00
2000-12-13 15:52:21 +03:00
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
2007-09-19 16:45:35 +04:00
2000-12-13 15:52:21 +03:00
You should have received a copy of the GNU General Public License
2007-07-10 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2000-12-13 15:52:21 +03:00
*/
# include "includes.h"
2011-04-13 16:32:16 +04:00
# include "rpc_client/rpc_client.h"
2011-01-18 18:32:20 +03:00
# include "../librpc/gen_ndr/ndr_lsa_c.h"
2010-05-18 20:26:16 +04:00
# include "rpc_client/cli_lsarpc.h"
2010-08-20 01:15:22 +04:00
# include "rpc_client/init_lsa.h"
2010-10-12 08:27:50 +04:00
# include "../libcli/security/security.h"
2017-04-01 17:51:07 +03:00
# include "lsa.h"
2000-12-13 15:52:21 +03:00
2002-01-06 06:48:41 +03:00
/** @defgroup lsa LSA - Local Security Architecture
2001-11-23 08:50:05 +03:00
* @ ingroup rpc_client
2001-11-15 09:03:22 +03:00
*
* @ {
* */
/**
* @ file cli_lsarpc . c
*
* RPC client routines for the LSA RPC pipe . LSA means " local
* security authority " , which is half of a password database.
* */
2010-09-07 13:24:52 +04:00
NTSTATUS dcerpc_lsa_open_policy ( struct dcerpc_binding_handle * h ,
2005-06-09 02:10:34 +04:00
TALLOC_CTX * mem_ctx ,
2010-09-07 13:24:52 +04:00
bool sec_qos ,
uint32_t des_access ,
struct policy_handle * pol ,
NTSTATUS * result )
2000-12-13 15:52:21 +03:00
{
2021-02-06 10:32:36 +03:00
struct lsa_ObjectAttribute attr = { . len = 0x18 , } ;
2008-02-11 19:50:18 +03:00
struct lsa_QosInfo qos ;
uint16_t system_name = ' \\ ' ;
2000-12-13 15:52:21 +03:00
if ( sec_qos ) {
2008-12-08 20:03:01 +03:00
qos . len = 0xc ;
qos . impersonation_level = 2 ;
qos . context_mode = 1 ;
qos . effective_only = 0 ;
attr . sec_qos = & qos ;
2000-12-13 15:52:21 +03:00
}
2010-09-07 13:24:52 +04:00
return dcerpc_lsa_OpenPolicy ( h ,
mem_ctx ,
2008-02-11 19:50:18 +03:00
& system_name ,
& attr ,
des_access ,
2010-09-07 13:24:52 +04:00
pol ,
result ) ;
}
/** Open a LSA policy handle
*
* @ param cli Handle on an initialised SMB connection */
NTSTATUS rpccli_lsa_open_policy ( struct rpc_pipe_client * cli ,
TALLOC_CTX * mem_ctx ,
2015-05-09 19:49:04 +03:00
bool sec_qos , uint32_t des_access ,
2010-09-07 13:24:52 +04:00
struct policy_handle * pol )
{
NTSTATUS status ;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
status = dcerpc_lsa_open_policy ( cli - > binding_handle ,
mem_ctx ,
sec_qos ,
des_access ,
pol ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
return result ;
2000-12-13 15:52:21 +03:00
}
2010-09-07 14:19:25 +04:00
NTSTATUS dcerpc_lsa_open_policy2 ( struct dcerpc_binding_handle * h ,
TALLOC_CTX * mem_ctx ,
const char * srv_name_slash ,
bool sec_qos ,
uint32_t des_access ,
struct policy_handle * pol ,
NTSTATUS * result )
2001-08-21 07:05:27 +04:00
{
2021-02-06 10:32:36 +03:00
struct lsa_ObjectAttribute attr = { . len = 0x18 , } ;
2008-02-11 19:50:18 +03:00
struct lsa_QosInfo qos ;
2001-08-21 07:05:27 +04:00
if ( sec_qos ) {
2008-12-08 20:03:01 +03:00
qos . len = 0xc ;
qos . impersonation_level = 2 ;
qos . context_mode = 1 ;
qos . effective_only = 0 ;
attr . sec_qos = & qos ;
2001-08-21 07:05:27 +04:00
}
2010-09-07 14:19:25 +04:00
return dcerpc_lsa_OpenPolicy2 ( h ,
mem_ctx ,
srv_name_slash ,
2008-02-11 19:50:18 +03:00
& attr ,
des_access ,
2010-09-07 14:19:25 +04:00
pol ,
result ) ;
}
2023-08-31 11:18:23 +03:00
NTSTATUS dcerpc_lsa_open_policy3 ( struct dcerpc_binding_handle * h ,
TALLOC_CTX * mem_ctx ,
const char * srv_name_slash ,
bool sec_qos ,
uint32_t des_access ,
uint32_t * out_version ,
union lsa_revision_info * out_revision_info ,
struct policy_handle * pol ,
NTSTATUS * result )
{
struct lsa_ObjectAttribute attr = { . len = 0x18 , } ;
struct lsa_QosInfo qos ;
union lsa_revision_info in_revision_info = {
. info1 = {
. revision = 1 ,
} ,
} ;
uint32_t in_version = 1 ;
if ( sec_qos ) {
qos . len = 0xc ;
qos . impersonation_level = 2 ;
qos . context_mode = 1 ;
qos . effective_only = 0 ;
attr . sec_qos = & qos ;
}
return dcerpc_lsa_OpenPolicy3 ( h ,
mem_ctx ,
srv_name_slash ,
& attr ,
des_access ,
in_version ,
& in_revision_info ,
out_version ,
out_revision_info ,
pol ,
result ) ;
}
2023-10-23 16:35:38 +03:00
NTSTATUS dcerpc_lsa_open_policy_fallback ( struct dcerpc_binding_handle * h ,
TALLOC_CTX * mem_ctx ,
const char * srv_name_slash ,
bool sec_qos ,
uint32_t desired_access ,
uint32_t * out_version ,
union lsa_revision_info * out_revision_info ,
struct policy_handle * pol ,
NTSTATUS * result )
{
NTSTATUS status ;
status = dcerpc_lsa_open_policy3 ( h ,
mem_ctx ,
srv_name_slash ,
sec_qos ,
desired_access ,
out_version ,
out_revision_info ,
pol ,
result ) ;
if ( NT_STATUS_EQUAL ( status , NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE ) ) {
* out_version = 1 ;
* out_revision_info = ( union lsa_revision_info ) {
. info1 = {
. revision = 1 ,
}
} ;
status = dcerpc_lsa_open_policy2 ( h ,
mem_ctx ,
srv_name_slash ,
sec_qos ,
desired_access ,
pol ,
result ) ;
}
return status ;
}
2007-05-22 15:30:35 +04:00
/* Lookup a list of sids
*
2007-05-22 17:40:01 +04:00
* internal version withOUT memory allocation of the target arrays .
2011-03-10 19:11:37 +03:00
* this assumes sufficiently sized arrays to store domains , names and types . */
2007-05-22 15:30:35 +04:00
2010-09-07 16:58:19 +04:00
static NTSTATUS dcerpc_lsa_lookup_sids_noalloc ( struct dcerpc_binding_handle * h ,
2007-05-22 15:30:35 +04:00
TALLOC_CTX * mem_ctx ,
2012-03-13 21:07:11 +04:00
TALLOC_CTX * domains_ctx ,
TALLOC_CTX * names_ctx ,
2009-03-19 00:49:41 +03:00
struct policy_handle * pol ,
2007-05-22 15:30:35 +04:00
int num_sids ,
2010-05-21 05:25:01 +04:00
const struct dom_sid * sids ,
2018-01-15 14:57:11 +03:00
enum lsa_LookupNamesLevel level ,
2007-05-22 15:30:35 +04:00
char * * domains ,
char * * names ,
2009-09-13 02:28:49 +04:00
enum lsa_SidType * types ,
2010-09-07 16:58:19 +04:00
bool use_lookupsids3 ,
NTSTATUS * presult )
2007-05-22 15:30:35 +04:00
{
2019-09-05 17:22:02 +03:00
NTSTATUS status ;
2010-09-07 16:58:19 +04:00
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
2008-02-18 12:03:19 +03:00
struct lsa_SidArray sid_array ;
struct lsa_RefDomainList * ref_domains = NULL ;
2021-02-06 10:32:36 +03:00
struct lsa_TransNameArray lsa_names = { . count = 0 , } ;
2008-02-18 12:03:19 +03:00
uint32_t count = 0 ;
2010-09-07 16:58:19 +04:00
int i ;
2008-02-18 12:03:19 +03:00
sid_array . num_sids = num_sids ;
2011-06-07 05:30:12 +04:00
sid_array . sids = talloc_array ( mem_ctx , struct lsa_SidPtr , num_sids ) ;
2010-09-07 16:58:19 +04:00
if ( sid_array . sids = = NULL ) {
2008-02-18 12:03:19 +03:00
return NT_STATUS_NO_MEMORY ;
}
2007-05-22 15:30:35 +04:00
2008-02-18 12:03:19 +03:00
for ( i = 0 ; i < num_sids ; i + + ) {
2010-08-26 19:21:39 +04:00
sid_array . sids [ i ] . sid = dom_sid_dup ( mem_ctx , & sids [ i ] ) ;
2008-02-18 12:03:19 +03:00
if ( ! sid_array . sids [ i ] . sid ) {
return NT_STATUS_NO_MEMORY ;
}
}
2007-05-22 15:30:35 +04:00
2009-09-13 02:28:49 +04:00
if ( use_lookupsids3 ) {
struct lsa_TransNameArray2 lsa_names2 ;
uint32_t n ;
2009-09-17 11:42:49 +04:00
ZERO_STRUCT ( lsa_names2 ) ;
2010-09-07 16:58:19 +04:00
status = dcerpc_lsa_LookupSids3 ( h ,
mem_ctx ,
2009-09-13 02:28:49 +04:00
& sid_array ,
& ref_domains ,
& lsa_names2 ,
level ,
& count ,
2011-01-05 19:22:18 +03:00
LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES ,
2011-01-05 19:24:51 +03:00
LSA_CLIENT_REVISION_2 ,
2010-09-07 16:58:19 +04:00
& result ) ;
2011-01-17 15:40:12 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2010-09-07 16:58:19 +04:00
return status ;
}
2009-09-13 02:28:49 +04:00
2017-04-01 17:51:07 +03:00
if ( ! NT_STATUS_LOOKUP_ERR ( result ) ) {
2010-09-07 16:58:19 +04:00
lsa_names . count = lsa_names2 . count ;
lsa_names . names = talloc_array ( mem_ctx ,
struct lsa_TranslatedName ,
lsa_names . count ) ;
if ( lsa_names . names = = NULL ) {
2009-09-13 02:28:49 +04:00
return NT_STATUS_NO_MEMORY ;
}
for ( n = 0 ; n < lsa_names . count ; n + + ) {
lsa_names . names [ n ] . sid_type = lsa_names2 . names [ n ] . sid_type ;
lsa_names . names [ n ] . name = lsa_names2 . names [ n ] . name ;
lsa_names . names [ n ] . sid_index = lsa_names2 . names [ n ] . sid_index ;
}
}
} else {
2010-09-07 16:58:19 +04:00
status = dcerpc_lsa_LookupSids ( h ,
mem_ctx ,
2009-09-13 02:28:49 +04:00
pol ,
& sid_array ,
& ref_domains ,
& lsa_names ,
level ,
2010-09-07 16:58:19 +04:00
& count ,
& result ) ;
2009-09-13 02:28:49 +04:00
}
2007-05-22 15:30:35 +04:00
2010-09-07 16:58:19 +04:00
DEBUG ( 10 , ( " LSA_LOOKUPSIDS returned status: '%s', result: '%s', "
" mapped count = %d' \n " ,
nt_errstr ( status ) , nt_errstr ( result ) , count ) ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2007-09-19 16:05:47 +04:00
2017-04-01 17:56:39 +03:00
if ( NT_STATUS_LOOKUP_ERR ( result ) ) {
2010-09-07 16:58:19 +04:00
* presult = result ;
return status ;
2007-05-22 15:30:35 +04:00
}
/* Return output parameters */
2008-02-18 12:03:19 +03:00
if ( NT_STATUS_EQUAL ( result , NT_STATUS_NONE_MAPPED ) | |
( count = = 0 ) )
2007-09-19 16:03:02 +04:00
{
2007-08-29 18:34:15 +04:00
for ( i = 0 ; i < num_sids ; i + + ) {
( names ) [ i ] = NULL ;
( domains ) [ i ] = NULL ;
( types ) [ i ] = SID_NAME_UNKNOWN ;
}
2010-09-07 16:58:19 +04:00
* presult = NT_STATUS_NONE_MAPPED ;
return status ;
2007-05-22 15:30:35 +04:00
}
for ( i = 0 ; i < num_sids ; i + + ) {
2008-02-18 12:03:19 +03:00
const char * name , * dom_name ;
2013-11-08 08:38:01 +04:00
uint32_t dom_idx ;
if ( i > = lsa_names . count ) {
* presult = NT_STATUS_INVALID_NETWORK_RESPONSE ;
return status ;
}
dom_idx = lsa_names . names [ i ] . sid_index ;
2007-05-22 15:30:35 +04:00
/* Translate optimised name through domain index array */
if ( dom_idx ! = 0xffffffff ) {
2013-11-08 08:38:01 +04:00
if ( ref_domains = = NULL ) {
* presult = NT_STATUS_INVALID_NETWORK_RESPONSE ;
return status ;
}
if ( dom_idx > = ref_domains - > count ) {
* presult = NT_STATUS_INVALID_NETWORK_RESPONSE ;
return status ;
}
2007-05-22 15:30:35 +04:00
2008-02-18 12:03:19 +03:00
dom_name = ref_domains - > domains [ dom_idx ] . name . string ;
name = lsa_names . names [ i ] . name . string ;
2007-05-22 15:30:35 +04:00
2008-04-03 02:23:50 +04:00
if ( name ) {
2012-03-13 21:07:11 +04:00
( names ) [ i ] = talloc_strdup ( names_ctx , name ) ;
2008-04-03 02:23:50 +04:00
if ( ( names ) [ i ] = = NULL ) {
DEBUG ( 0 , ( " cli_lsa_lookup_sids_noalloc(): out of memory \n " ) ) ;
2010-09-07 16:58:19 +04:00
* presult = NT_STATUS_UNSUCCESSFUL ;
return status ;
2008-04-03 02:23:50 +04:00
}
} else {
( names ) [ i ] = NULL ;
}
2012-03-13 21:07:11 +04:00
domains [ i ] = talloc_strdup ( domains_ctx ,
2010-06-11 13:48:37 +04:00
dom_name ? dom_name : " " ) ;
2008-02-18 12:03:19 +03:00
( types ) [ i ] = lsa_names . names [ i ] . sid_type ;
2012-03-09 19:24:56 +04:00
if ( ( domains ) [ i ] = = NULL ) {
2007-06-09 04:13:07 +04:00
DEBUG ( 0 , ( " cli_lsa_lookup_sids_noalloc(): out of memory \n " ) ) ;
2010-09-07 16:58:19 +04:00
* presult = NT_STATUS_UNSUCCESSFUL ;
return status ;
2007-05-22 15:30:35 +04:00
}
} else {
2007-05-23 01:17:31 +04:00
( names ) [ i ] = NULL ;
( domains ) [ i ] = NULL ;
2007-05-22 15:30:35 +04:00
( types ) [ i ] = SID_NAME_UNKNOWN ;
}
}
2010-09-07 16:58:19 +04:00
* presult = NT_STATUS_OK ;
return status ;
2007-05-22 15:30:35 +04:00
}
2007-09-19 16:45:35 +04:00
/* Lookup a list of sids
2007-05-22 15:30:35 +04:00
*
* do it the right way : there is a limit ( of 20480 for w2k3 ) entries
* returned by this call . when the sids list contains more entries ,
* empty lists are returned . This version of lsa_lookup_sids passes
* the list of sids in hunks of LOOKUP_SIDS_HUNK_SIZE to the lsa call . */
/* This constant defines the limit of how many sids to look up
* in one call ( maximum ) . the limit from the server side is
* at 20480 for win2k3 , but we keep it at a save 1000 for now . */
# define LOOKUP_SIDS_HUNK_SIZE 1000
2012-11-28 19:57:57 +04:00
NTSTATUS dcerpc_lsa_lookup_sids_generic ( struct dcerpc_binding_handle * h ,
TALLOC_CTX * mem_ctx ,
struct policy_handle * pol ,
int num_sids ,
const struct dom_sid * sids ,
2018-01-15 14:57:11 +03:00
enum lsa_LookupNamesLevel level ,
2012-11-28 19:57:57 +04:00
char * * * pdomains ,
char * * * pnames ,
enum lsa_SidType * * ptypes ,
bool use_lookupsids3 ,
NTSTATUS * presult )
2007-05-22 15:30:35 +04:00
{
2011-02-09 11:46:43 +03:00
NTSTATUS status = NT_STATUS_OK ;
2007-05-22 15:30:35 +04:00
NTSTATUS result = NT_STATUS_OK ;
int sids_left = 0 ;
int sids_processed = 0 ;
2010-05-21 05:25:01 +04:00
const struct dom_sid * hunk_sids = sids ;
2008-03-05 18:20:34 +03:00
char * * hunk_domains ;
char * * hunk_names ;
enum lsa_SidType * hunk_types ;
char * * domains = NULL ;
char * * names = NULL ;
enum lsa_SidType * types = NULL ;
2010-11-23 16:28:45 +03:00
bool have_mapped = false ;
bool have_unmapped = false ;
2007-05-22 15:30:35 +04:00
if ( num_sids ) {
2018-02-02 14:07:11 +03:00
domains = talloc_zero_array ( mem_ctx , char * , num_sids ) ;
if ( domains = = NULL ) {
2007-09-20 02:11:09 +04:00
DEBUG ( 0 , ( " rpccli_lsa_lookup_sids(): out of memory \n " ) ) ;
2011-01-17 15:39:21 +03:00
status = NT_STATUS_NO_MEMORY ;
2007-09-19 15:01:44 +04:00
goto fail ;
2007-05-22 15:30:35 +04:00
}
2018-02-02 14:07:11 +03:00
names = talloc_zero_array ( mem_ctx , char * , num_sids ) ;
if ( names = = NULL ) {
2007-09-20 02:11:09 +04:00
DEBUG ( 0 , ( " rpccli_lsa_lookup_sids(): out of memory \n " ) ) ;
2011-01-17 15:39:21 +03:00
status = NT_STATUS_NO_MEMORY ;
2007-09-19 15:01:44 +04:00
goto fail ;
2007-05-22 15:30:35 +04:00
}
2018-02-02 14:07:11 +03:00
types = talloc_zero_array ( mem_ctx , enum lsa_SidType , num_sids ) ;
if ( types = = NULL ) {
2007-09-20 02:11:09 +04:00
DEBUG ( 0 , ( " rpccli_lsa_lookup_sids(): out of memory \n " ) ) ;
2011-01-17 15:39:21 +03:00
status = NT_STATUS_NO_MEMORY ;
2007-09-19 15:01:44 +04:00
goto fail ;
2007-05-22 15:30:35 +04:00
}
}
2007-09-19 16:45:35 +04:00
2007-05-22 15:30:35 +04:00
sids_left = num_sids ;
2008-03-05 18:20:34 +03:00
hunk_domains = domains ;
hunk_names = names ;
hunk_types = types ;
2007-05-22 15:30:35 +04:00
while ( sids_left > 0 ) {
int hunk_num_sids ;
2011-01-17 15:39:21 +03:00
NTSTATUS hunk_result = NT_STATUS_UNSUCCESSFUL ;
2007-05-22 15:30:35 +04:00
2007-09-19 16:45:35 +04:00
hunk_num_sids = ( ( sids_left > LOOKUP_SIDS_HUNK_SIZE )
? LOOKUP_SIDS_HUNK_SIZE
2007-05-22 15:30:35 +04:00
: sids_left ) ;
2007-09-20 02:11:09 +04:00
DEBUG ( 10 , ( " rpccli_lsa_lookup_sids: processing items "
2007-09-19 16:45:35 +04:00
" %d -- %d of %d. \n " ,
sids_processed ,
2007-05-22 15:30:35 +04:00
sids_processed + hunk_num_sids - 1 ,
num_sids ) ) ;
2010-09-07 16:58:19 +04:00
status = dcerpc_lsa_lookup_sids_noalloc ( h ,
mem_ctx ,
2012-03-13 21:07:11 +04:00
( TALLOC_CTX * ) domains ,
( TALLOC_CTX * ) names ,
2010-09-07 16:58:19 +04:00
pol ,
hunk_num_sids ,
hunk_sids ,
2018-01-15 14:57:11 +03:00
level ,
2010-09-07 16:58:19 +04:00
hunk_domains ,
hunk_names ,
hunk_types ,
use_lookupsids3 ,
& hunk_result ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto fail ;
}
2007-05-22 15:30:35 +04:00
if ( ! NT_STATUS_IS_OK ( hunk_result ) & &
! NT_STATUS_EQUAL ( hunk_result , STATUS_SOME_UNMAPPED ) & &
2007-09-19 16:45:35 +04:00
! NT_STATUS_EQUAL ( hunk_result , NT_STATUS_NONE_MAPPED ) )
2007-05-22 15:30:35 +04:00
{
2017-02-17 22:46:28 +03:00
/* An actual error occurred */
2010-09-07 16:58:19 +04:00
* presult = hunk_result ;
2007-09-19 15:01:44 +04:00
goto fail ;
2007-05-22 15:30:35 +04:00
}
2010-11-23 16:28:45 +03:00
if ( NT_STATUS_IS_OK ( hunk_result ) ) {
have_mapped = true ;
}
if ( NT_STATUS_EQUAL ( hunk_result , NT_STATUS_NONE_MAPPED ) ) {
have_unmapped = true ;
}
if ( NT_STATUS_EQUAL ( hunk_result , STATUS_SOME_UNMAPPED ) ) {
int i ;
for ( i = 0 ; i < hunk_num_sids ; i + + ) {
if ( hunk_types [ i ] = = SID_NAME_UNKNOWN ) {
have_unmapped = true ;
} else {
have_mapped = true ;
}
}
2007-05-22 15:30:35 +04:00
}
sids_left - = hunk_num_sids ;
2012-03-13 21:07:11 +04:00
sids_processed + = hunk_num_sids ;
2007-05-22 15:30:35 +04:00
hunk_sids + = hunk_num_sids ;
hunk_domains + = hunk_num_sids ;
hunk_names + = hunk_num_sids ;
hunk_types + = hunk_num_sids ;
}
2008-03-05 18:20:34 +03:00
* pdomains = domains ;
* pnames = names ;
* ptypes = types ;
2010-11-23 16:28:45 +03:00
if ( ! have_mapped ) {
2010-09-07 16:58:19 +04:00
result = NT_STATUS_NONE_MAPPED ;
2010-11-23 16:28:45 +03:00
}
if ( have_unmapped ) {
2010-09-07 16:58:19 +04:00
result = STATUS_SOME_UNMAPPED ;
2010-11-23 16:28:45 +03:00
}
2010-09-07 16:58:19 +04:00
* presult = result ;
return status ;
2007-09-19 15:01:44 +04:00
fail :
2008-03-05 18:20:34 +03:00
TALLOC_FREE ( domains ) ;
TALLOC_FREE ( names ) ;
TALLOC_FREE ( types ) ;
2010-09-07 16:58:19 +04:00
return status ;
}
NTSTATUS dcerpc_lsa_lookup_sids ( struct dcerpc_binding_handle * h ,
TALLOC_CTX * mem_ctx ,
struct policy_handle * pol ,
int num_sids ,
const struct dom_sid * sids ,
char * * * pdomains ,
char * * * pnames ,
enum lsa_SidType * * ptypes ,
NTSTATUS * result )
{
2018-01-15 14:57:11 +03:00
enum lsa_LookupNamesLevel level = LSA_LOOKUP_NAMES_ALL ;
2010-09-07 16:58:19 +04:00
return dcerpc_lsa_lookup_sids_generic ( h ,
mem_ctx ,
pol ,
num_sids ,
sids ,
2018-01-15 14:57:11 +03:00
level ,
2010-09-07 16:58:19 +04:00
pdomains ,
pnames ,
ptypes ,
false ,
result ) ;
2007-05-22 15:30:35 +04:00
}
2009-09-13 02:28:49 +04:00
NTSTATUS rpccli_lsa_lookup_sids ( struct rpc_pipe_client * cli ,
TALLOC_CTX * mem_ctx ,
struct policy_handle * pol ,
int num_sids ,
2010-05-21 05:25:01 +04:00
const struct dom_sid * sids ,
2009-09-13 02:28:49 +04:00
char * * * pdomains ,
char * * * pnames ,
enum lsa_SidType * * ptypes )
{
2010-09-07 16:58:19 +04:00
NTSTATUS status ;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
2018-01-15 14:57:11 +03:00
enum lsa_LookupNamesLevel level = LSA_LOOKUP_NAMES_ALL ;
2010-09-07 16:58:19 +04:00
status = dcerpc_lsa_lookup_sids_generic ( cli - > binding_handle ,
mem_ctx ,
pol ,
num_sids ,
sids ,
2018-01-15 14:57:11 +03:00
level ,
2010-09-07 16:58:19 +04:00
pdomains ,
pnames ,
ptypes ,
false ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
return result ;
}
NTSTATUS dcerpc_lsa_lookup_sids3 ( struct dcerpc_binding_handle * h ,
TALLOC_CTX * mem_ctx ,
struct policy_handle * pol ,
int num_sids ,
const struct dom_sid * sids ,
char * * * pdomains ,
char * * * pnames ,
enum lsa_SidType * * ptypes ,
NTSTATUS * result )
{
2018-01-15 14:57:11 +03:00
enum lsa_LookupNamesLevel level = LSA_LOOKUP_NAMES_ALL ;
2010-09-07 16:58:19 +04:00
return dcerpc_lsa_lookup_sids_generic ( h ,
mem_ctx ,
pol ,
num_sids ,
sids ,
2018-01-15 14:57:11 +03:00
level ,
2010-09-07 16:58:19 +04:00
pdomains ,
pnames ,
ptypes ,
true ,
result ) ;
2009-09-13 02:28:49 +04:00
}
2001-11-15 09:03:22 +03:00
/** Lookup a list of names */
2000-12-13 15:52:21 +03:00
2012-11-28 20:00:49 +04:00
NTSTATUS dcerpc_lsa_lookup_names_generic ( struct dcerpc_binding_handle * h ,
TALLOC_CTX * mem_ctx ,
struct policy_handle * pol ,
uint32_t num_names ,
const char * * names ,
const char * * * dom_names ,
enum lsa_LookupNamesLevel level ,
struct dom_sid * * sids ,
enum lsa_SidType * * types ,
bool use_lookupnames4 ,
NTSTATUS * presult )
2000-12-13 15:52:21 +03:00
{
2010-09-07 17:49:00 +04:00
NTSTATUS status ;
2008-02-18 06:30:57 +03:00
struct lsa_String * lsa_names = NULL ;
struct lsa_RefDomainList * domains = NULL ;
2021-02-06 10:32:36 +03:00
struct lsa_TransSidArray sid_array = { . count = 0 , } ;
struct lsa_TransSidArray3 sid_array3 = { . count = 0 , } ;
2008-02-18 06:30:57 +03:00
uint32_t count = 0 ;
2010-09-07 17:49:00 +04:00
uint32_t i ;
2007-09-19 16:45:35 +04:00
2011-06-07 05:30:12 +04:00
lsa_names = talloc_array ( mem_ctx , struct lsa_String , num_names ) ;
2010-09-07 17:49:00 +04:00
if ( lsa_names = = NULL ) {
2008-02-18 06:30:57 +03:00
return NT_STATUS_NO_MEMORY ;
}
2005-09-30 21:13:37 +04:00
2010-09-07 17:49:00 +04:00
for ( i = 0 ; i < num_names ; i + + ) {
2008-02-18 06:30:57 +03:00
init_lsa_String ( & lsa_names [ i ] , names [ i ] ) ;
}
2000-12-13 15:52:21 +03:00
2009-09-11 21:35:14 +04:00
if ( use_lookupnames4 ) {
2010-09-07 17:49:00 +04:00
status = dcerpc_lsa_LookupNames4 ( h ,
mem_ctx ,
2009-09-11 21:35:14 +04:00
num_names ,
lsa_names ,
& domains ,
& sid_array3 ,
level ,
& count ,
2011-01-05 19:34:30 +03:00
LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES ,
2011-01-05 19:35:36 +03:00
LSA_CLIENT_REVISION_2 ,
2010-09-07 17:49:00 +04:00
presult ) ;
2009-09-11 21:35:14 +04:00
} else {
2010-09-07 17:49:00 +04:00
status = dcerpc_lsa_LookupNames ( h ,
mem_ctx ,
pol ,
2009-09-11 21:35:14 +04:00
num_names ,
lsa_names ,
& domains ,
& sid_array ,
level ,
2010-09-07 17:49:00 +04:00
& count ,
presult ) ;
}
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto done ;
2009-09-11 21:35:14 +04:00
}
2000-12-13 15:52:21 +03:00
2010-09-07 17:49:00 +04:00
if ( ! NT_STATUS_IS_OK ( * presult ) & &
! NT_STATUS_EQUAL ( * presult , STATUS_SOME_UNMAPPED ) ) {
2017-02-17 22:46:28 +03:00
/* An actual error occurred */
2000-12-13 15:52:21 +03:00
goto done ;
}
/* Return output parameters */
2008-02-18 06:30:57 +03:00
if ( count = = 0 ) {
2010-09-07 17:49:00 +04:00
* presult = NT_STATUS_NONE_MAPPED ;
2001-11-22 11:31:50 +03:00
goto done ;
}
2007-04-30 06:39:34 +04:00
if ( num_names ) {
2018-02-02 14:07:11 +03:00
* sids = talloc_zero_array ( mem_ctx , struct dom_sid , num_names ) ;
if ( * sids = = NULL ) {
2007-04-30 06:39:34 +04:00
DEBUG ( 0 , ( " cli_lsa_lookup_sids(): out of memory \n " ) ) ;
2010-09-07 17:49:00 +04:00
* presult = NT_STATUS_NO_MEMORY ;
2007-04-30 06:39:34 +04:00
goto done ;
}
2000-12-13 15:52:21 +03:00
2018-02-02 14:07:11 +03:00
* types = talloc_zero_array ( mem_ctx , enum lsa_SidType , num_names ) ;
if ( * types = = NULL ) {
2006-02-04 01:19:41 +03:00
DEBUG ( 0 , ( " cli_lsa_lookup_sids(): out of memory \n " ) ) ;
2010-09-07 17:49:00 +04:00
* presult = NT_STATUS_NO_MEMORY ;
2006-02-04 01:19:41 +03:00
goto done ;
}
2007-04-30 06:39:34 +04:00
if ( dom_names ! = NULL ) {
2018-02-02 14:07:11 +03:00
* dom_names = talloc_zero_array ( mem_ctx , const char * , num_names ) ;
2007-04-30 06:39:34 +04:00
if ( * dom_names = = NULL ) {
DEBUG ( 0 , ( " cli_lsa_lookup_sids(): out of memory \n " ) ) ;
2010-09-07 17:49:00 +04:00
* presult = NT_STATUS_NO_MEMORY ;
2007-04-30 06:39:34 +04:00
goto done ;
}
}
} else {
* sids = NULL ;
* types = NULL ;
if ( dom_names ! = NULL ) {
* dom_names = NULL ;
}
2006-02-04 01:19:41 +03:00
}
2002-04-14 15:21:25 +04:00
for ( i = 0 ; i < num_names ; i + + ) {
2009-09-11 21:35:14 +04:00
uint32_t dom_idx ;
2010-05-21 05:25:01 +04:00
struct dom_sid * sid = & ( * sids ) [ i ] ;
2000-12-13 15:52:21 +03:00
2009-09-11 21:35:14 +04:00
if ( use_lookupnames4 ) {
2013-11-08 09:40:55 +04:00
if ( i > = sid_array3 . count ) {
* presult = NT_STATUS_INVALID_NETWORK_RESPONSE ;
goto done ;
}
2009-09-11 21:35:14 +04:00
dom_idx = sid_array3 . sids [ i ] . sid_index ;
( * types ) [ i ] = sid_array3 . sids [ i ] . sid_type ;
} else {
2013-11-08 09:40:55 +04:00
if ( i > = sid_array . count ) {
* presult = NT_STATUS_INVALID_NETWORK_RESPONSE ;
goto done ;
}
2009-09-11 21:35:14 +04:00
dom_idx = sid_array . sids [ i ] . sid_index ;
( * types ) [ i ] = sid_array . sids [ i ] . sid_type ;
}
2000-12-13 15:52:21 +03:00
/* Translate optimised sid through domain index array */
2006-02-04 01:19:41 +03:00
if ( dom_idx = = 0xffffffff ) {
/* Nothing to do, this is unknown */
ZERO_STRUCTP ( sid ) ;
( * types ) [ i ] = SID_NAME_UNKNOWN ;
continue ;
}
2013-11-08 09:40:55 +04:00
if ( domains = = NULL ) {
* presult = NT_STATUS_INVALID_NETWORK_RESPONSE ;
goto done ;
}
if ( dom_idx > = domains - > count ) {
* presult = NT_STATUS_INVALID_NETWORK_RESPONSE ;
goto done ;
}
2000-12-13 15:52:21 +03:00
2009-09-11 21:35:14 +04:00
if ( use_lookupnames4 ) {
sid_copy ( sid , sid_array3 . sids [ i ] . sid ) ;
} else {
sid_copy ( sid , domains - > domains [ dom_idx ] . sid ) ;
2000-12-13 15:52:21 +03:00
2009-09-11 21:35:14 +04:00
if ( sid_array . sids [ i ] . rid ! = 0xffffffff ) {
sid_append_rid ( sid , sid_array . sids [ i ] . rid ) ;
}
2006-02-04 01:19:41 +03:00
}
2000-12-13 15:52:21 +03:00
2006-02-04 01:19:41 +03:00
if ( dom_names = = NULL ) {
continue ;
2000-12-13 15:52:21 +03:00
}
2006-02-04 01:19:41 +03:00
2008-02-18 06:30:57 +03:00
( * dom_names ) [ i ] = domains - > domains [ dom_idx ] . name . string ;
2000-12-13 15:52:21 +03:00
}
done :
2010-09-07 17:49:00 +04:00
return status ;
}
2000-12-15 04:02:11 +03:00
2010-09-07 17:49:00 +04:00
NTSTATUS dcerpc_lsa_lookup_names ( struct dcerpc_binding_handle * h ,
TALLOC_CTX * mem_ctx ,
struct policy_handle * pol ,
uint32_t num_names ,
const char * * names ,
const char * * * dom_names ,
enum lsa_LookupNamesLevel level ,
struct dom_sid * * sids ,
enum lsa_SidType * * types ,
NTSTATUS * result )
{
return dcerpc_lsa_lookup_names_generic ( h ,
mem_ctx ,
pol ,
num_names ,
names ,
dom_names ,
level ,
sids ,
types ,
false ,
result ) ;
2002-08-12 17:40:59 +04:00
}
2009-09-11 21:35:14 +04:00
NTSTATUS rpccli_lsa_lookup_names ( struct rpc_pipe_client * cli ,
TALLOC_CTX * mem_ctx ,
2010-09-07 17:49:00 +04:00
struct policy_handle * pol ,
int num_names ,
2009-09-11 21:35:14 +04:00
const char * * names ,
const char * * * dom_names ,
int level ,
2010-05-21 05:25:01 +04:00
struct dom_sid * * sids ,
2009-09-11 21:35:14 +04:00
enum lsa_SidType * * types )
{
2010-09-07 17:49:00 +04:00
NTSTATUS status ;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
status = dcerpc_lsa_lookup_names ( cli - > binding_handle ,
mem_ctx ,
pol ,
num_names ,
names ,
dom_names ,
level ,
sids ,
types ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
return result ;
}
NTSTATUS dcerpc_lsa_lookup_names4 ( struct dcerpc_binding_handle * h ,
TALLOC_CTX * mem_ctx ,
struct policy_handle * pol ,
uint32_t num_names ,
const char * * names ,
const char * * * dom_names ,
enum lsa_LookupNamesLevel level ,
struct dom_sid * * sids ,
enum lsa_SidType * * types ,
NTSTATUS * result )
{
return dcerpc_lsa_lookup_names_generic ( h ,
mem_ctx ,
pol ,
num_names ,
names ,
dom_names ,
level ,
sids ,
types ,
true ,
result ) ;
2009-09-11 21:35:14 +04:00
}