2005-09-03 16:55:45 +00:00
/*
* Unix SMB / CIFS implementation .
* MS - RPC client library implementation ( LSA pipe )
* Copyright ( C ) Chris Nicholls 2005.
*
* 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
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* 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 .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "libmsrpc.h"
# include "libsmb_internal.h"
int cac_LsaOpenPolicy ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct LsaOpenPolicy * op ) {
SMBCSRV * srv = NULL ;
POLICY_HND * policy = NULL ;
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! mem_ctx | | ! op ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
op - > out . pol = NULL ;
srv = cac_GetServer ( hnd ) ;
if ( ! srv ) {
hnd - > status = NT_STATUS_INVALID_CONNECTION ;
return CAC_FAILURE ;
}
/*see if there is already an active session on this pipe, if not then open one*/
if ( ! hnd - > _internal . pipes [ PI_LSARPC ] ) {
2005-10-17 16:44:26 +00:00
pipe_hnd = cli_rpc_pipe_open_noauth ( & ( srv - > cli ) , PI_LSARPC , & ( hnd - > status ) ) ;
if ( ! pipe_hnd ) {
2005-09-03 16:55:45 +00:00
hnd - > status = NT_STATUS_UNSUCCESSFUL ;
return CAC_FAILURE ;
}
hnd - > _internal . pipes [ PI_LSARPC ] = True ;
}
policy = SMB_MALLOC_P ( POLICY_HND ) ;
if ( ! policy ) {
errno = ENOMEM ;
hnd - > status = NT_STATUS_NO_MEMORY ;
return CAC_FAILURE ;
}
/*need to make sure that our nt status is good otherwise check might fail below*/
hnd - > status = NT_STATUS_OK ;
if ( hnd - > _internal . srv_level > = SRV_WIN_2K ) {
/*try using open_policy2, if this fails try again in next block using open_policy, if that works then adjust hnd->_internal.srv_level*/
/*we shouldn't need to modify the access mask to make it work here*/
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_lsa_open_policy2 ( pipe_hnd , mem_ctx , op - > in . security_qos , op - > in . access , policy ) ;
2005-09-03 16:55:45 +00:00
}
if ( hnd - > _internal . srv_level < SRV_WIN_2K | | ! NT_STATUS_IS_OK ( hnd - > status ) ) {
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_lsa_open_policy ( pipe_hnd , mem_ctx , op - > in . security_qos , op - > in . access , policy ) ;
2005-09-03 16:55:45 +00:00
if ( hnd - > _internal . srv_level > SRV_WIN_NT4 & & NT_STATUS_IS_OK ( hnd - > status ) ) {
/*change the server level to 1*/
hnd - > _internal . srv_level = SRV_WIN_NT4 ;
}
}
if ( ! NT_STATUS_IS_OK ( hnd - > status ) ) {
SAFE_FREE ( policy ) ;
return CAC_FAILURE ;
}
op - > out . pol = policy ;
return CAC_SUCCESS ;
}
int cac_LsaClosePolicy ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , POLICY_HND * pol ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
if ( ! hnd )
return CAC_FAILURE ;
if ( ! pol )
return CAC_SUCCESS ; /*if the policy handle doesnt exist then it's already closed*/
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_LSARPC ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_LSARPC ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_lsa_close ( pipe_hnd , mem_ctx , pol ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
SAFE_FREE ( pol ) ;
return CAC_SUCCESS ;
}
int cac_LsaGetNamesFromSids ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct LsaGetNamesFromSids * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
int result = - 1 ;
int i ;
/*buffers for outputs*/
char * * domains = NULL ;
char * * names = NULL ;
uint32 * types = NULL ;
CacSidInfo * sids_out = NULL ;
DOM_SID * unknown_out = NULL ;
int num_unknown = 0 ;
int num_sids ;
int found_idx ;
int unknown_idx ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_LSARPC ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! mem_ctx | | ! op | | ! op - > in . pol | | ! op - > in . sids ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
num_sids = op - > in . num_sids ;
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_LSARPC ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
2005-09-03 16:55:45 +00:00
/*now actually lookup the names*/
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_lsa_lookup_sids ( pipe_hnd , mem_ctx , op - > in . pol , op - > in . num_sids ,
2005-09-03 16:55:45 +00:00
op - > in . sids , & domains , & names , & types ) ;
if ( NT_STATUS_IS_OK ( hnd - > status ) ) {
/*this is the easy part, just make the out.sids array*/
sids_out = TALLOC_ARRAY ( mem_ctx , CacSidInfo , num_sids ) ;
if ( ! sids_out ) {
errno = ENOMEM ;
hnd - > status = NT_STATUS_NO_MEMORY ;
return CAC_FAILURE ;
}
for ( i = 0 ; i < num_sids ; i + + ) {
sids_out [ i ] . sid = op - > in . sids [ i ] ;
sids_out [ i ] . name = names [ i ] ;
sids_out [ i ] . domain = domains [ i ] ;
}
result = CAC_SUCCESS ;
}
else if ( NT_STATUS_V ( hnd - > status ) = = NT_STATUS_V ( STATUS_SOME_UNMAPPED ) ) {
/*first find out how many couldn't be looked up*/
for ( i = 0 ; i < num_sids ; i + + ) {
if ( names [ i ] = = NULL ) {
num_unknown + + ;
}
}
if ( num_unknown > = num_sids ) {
hnd - > status = NT_STATUS_UNSUCCESSFUL ;
return CAC_FAILURE ;
}
sids_out = TALLOC_ARRAY ( mem_ctx , CacSidInfo , ( num_sids - num_unknown ) ) ;
if ( ! sids_out ) {
errno = ENOMEM ;
hnd - > status = NT_STATUS_NO_MEMORY ;
return CAC_FAILURE ;
}
unknown_out = TALLOC_ARRAY ( mem_ctx , DOM_SID , num_unknown ) ;
if ( ! unknown_out ) {
errno = ENOMEM ;
hnd - > status = NT_STATUS_NO_MEMORY ;
return CAC_FAILURE ;
}
found_idx = unknown_idx = 0 ;
/*now we can actually do the real work*/
for ( i = 0 ; i < num_sids ; i + + ) {
if ( names [ i ] ! = NULL ) {
sids_out [ found_idx ] . sid = op - > in . sids [ i ] ;
sids_out [ found_idx ] . name = names [ i ] ;
sids_out [ found_idx ] . domain = domains [ i ] ;
found_idx + + ;
}
else { /*then this one didnt work out*/
unknown_out [ unknown_idx ] = op - > in . sids [ i ] ;
unknown_idx + + ;
}
}
result = CAC_PARTIAL_SUCCESS ;
}
else { /*then it failed for some reason*/
return CAC_FAILURE ;
}
op - > out . num_found = num_sids - num_unknown ;
op - > out . sids = sids_out ;
op - > out . unknown = unknown_out ;
return result ;
}
int cac_LsaGetSidsFromNames ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct LsaGetSidsFromNames * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
int result = - 1 ;
int i ;
/*buffers for outputs*/
DOM_SID * sids = NULL ;
uint32 * types = NULL ;
CacSidInfo * sids_out = NULL ;
char * * unknown_out = NULL ;
int num_unknown = 0 ;
int num_names ;
int found_idx = 0 ;
int unknown_idx = 0 ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_LSARPC ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! mem_ctx | | ! op | | ! op - > in . pol | | ! op - > in . names ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
num_names = op - > in . num_names ;
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_LSARPC ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
/*now actually lookup the names*/
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_lsa_lookup_names ( pipe_hnd , mem_ctx , op - > in . pol , num_names ,
2006-02-03 22:19:41 +00:00
( const char * * ) op - > in . names , NULL , & sids , & types ) ;
2005-09-03 16:55:45 +00:00
if ( NT_STATUS_IS_OK ( hnd - > status ) ) {
/*this is the easy part, just make the out.sids array*/
sids_out = TALLOC_ARRAY ( mem_ctx , CacSidInfo , num_names ) ;
if ( ! sids_out ) {
errno = ENOMEM ;
hnd - > status = NT_STATUS_NO_MEMORY ;
return CAC_FAILURE ;
}
for ( i = 0 ; i < num_names ; i + + ) {
sids_out [ i ] . sid = sids [ i ] ;
sids_out [ i ] . name = talloc_strdup ( mem_ctx , op - > in . names [ i ] ) ;
sids_out [ i ] . domain = NULL ;
}
result = CAC_SUCCESS ;
}
else if ( NT_STATUS_V ( hnd - > status ) = = NT_STATUS_V ( STATUS_SOME_UNMAPPED ) ) {
/*first find out how many couldn't be looked up*/
for ( i = 0 ; i < num_names ; i + + ) {
if ( types [ i ] = = SID_NAME_UNKNOWN ) {
num_unknown + + ;
}
}
if ( num_unknown > = num_names ) {
hnd - > status = NT_STATUS_UNSUCCESSFUL ;
return CAC_FAILURE ;
}
sids_out = TALLOC_ARRAY ( mem_ctx , CacSidInfo , ( num_names - num_unknown ) ) ;
if ( ! sids_out ) {
errno = ENOMEM ;
hnd - > status = NT_STATUS_NO_MEMORY ;
return CAC_FAILURE ;
}
unknown_out = TALLOC_ARRAY ( mem_ctx , char * , num_unknown ) ;
if ( ! unknown_out ) {
errno = ENOMEM ;
hnd - > status = NT_STATUS_NO_MEMORY ;
return CAC_FAILURE ;
}
unknown_idx = found_idx = 0 ;
/*now we can actually do the real work*/
for ( i = 0 ; i < num_names ; i + + ) {
if ( types [ i ] ! = SID_NAME_UNKNOWN ) {
sids_out [ found_idx ] . sid = sids [ i ] ;
sids_out [ found_idx ] . name = talloc_strdup ( mem_ctx , op - > in . names [ i ] ) ;
sids_out [ found_idx ] . domain = NULL ;
found_idx + + ;
}
else { /*then this one didnt work out*/
unknown_out [ unknown_idx ] = talloc_strdup ( mem_ctx , op - > in . names [ i ] ) ;
unknown_idx + + ;
}
}
result = CAC_PARTIAL_SUCCESS ;
}
else { /*then it failed for some reason*/
return CAC_FAILURE ;
}
op - > out . num_found = num_names - num_unknown ;
op - > out . sids = sids_out ;
op - > out . unknown = unknown_out ;
return result ;
}
int cac_LsaFetchSid ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct LsaFetchSid * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
int result = - 1 ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_LSARPC ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! mem_ctx | | ! op | | ! op - > in . pol ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_LSARPC ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
op - > out . local_sid = NULL ;
op - > out . domain_sid = NULL ;
if ( ( op - > in . info_class & CAC_LOCAL_INFO ) = = CAC_LOCAL_INFO ) {
DOM_SID * local_sid = NULL ;
char * dom_name = NULL ;
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_lsa_query_info_policy ( pipe_hnd , mem_ctx , op - > in . pol , CAC_LOCAL_INFO , & dom_name , & local_sid ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) ) {
result = CAC_FAILURE ;
goto domain ;
}
op - > out . local_sid = talloc ( mem_ctx , CacSidInfo ) ;
if ( ! op - > out . local_sid ) {
hnd - > status = NT_STATUS_NO_MEMORY ;
result = CAC_FAILURE ;
goto domain ;
}
op - > out . local_sid - > domain = dom_name ;
sid_copy ( & op - > out . local_sid - > sid , local_sid ) ;
2006-02-20 17:59:58 +00:00
TALLOC_FREE ( local_sid ) ;
2005-09-03 16:55:45 +00:00
}
domain :
if ( ( op - > in . info_class & CAC_DOMAIN_INFO ) = = CAC_DOMAIN_INFO ) {
DOM_SID * domain_sid ;
char * dom_name ;
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_lsa_query_info_policy ( pipe_hnd , mem_ctx , op - > in . pol , CAC_DOMAIN_INFO , & dom_name , & domain_sid ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) ) {
/*if we succeeded above, report partial success*/
result = ( result = = CAC_SUCCESS ) ? CAC_PARTIAL_SUCCESS : CAC_FAILURE ;
goto done ;
}
else if ( result = = CAC_FAILURE ) {
/*if we failed above but succeded here then report partial success*/
result = CAC_PARTIAL_SUCCESS ;
}
op - > out . domain_sid = talloc ( mem_ctx , CacSidInfo ) ;
if ( ! op - > out . domain_sid ) {
hnd - > status = NT_STATUS_NO_MEMORY ;
result = CAC_FAILURE ;
goto done ;
}
op - > out . domain_sid - > domain = dom_name ;
sid_copy ( & op - > out . domain_sid - > sid , domain_sid ) ;
2006-02-20 17:59:58 +00:00
TALLOC_FREE ( domain_sid ) ;
2005-09-03 16:55:45 +00:00
}
done :
return result ;
}
int cac_LsaQueryInfoPolicy ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct LsaQueryInfoPolicy * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
char * domain_name = NULL ;
char * dns_name = NULL ;
char * forest_name = NULL ;
struct uuid * domain_guid = NULL ;
DOM_SID * domain_sid = NULL ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_LSARPC ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op - > in . pol ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_LSARPC ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
/*only works if info_class parm is 12*/
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_lsa_query_info_policy2 ( pipe_hnd , mem_ctx , op - > in . pol , 12 ,
2005-09-03 16:55:45 +00:00
& domain_name , & dns_name , & forest_name , & domain_guid , & domain_sid ) ;
if ( ! NT_STATUS_IS_OK ( hnd - > status ) ) {
return CAC_FAILURE ;
}
op - > out . domain_name = domain_name ;
op - > out . dns_name = dns_name ;
op - > out . forest_name = forest_name ;
op - > out . domain_guid = domain_guid ;
op - > out . domain_sid = domain_sid ;
return CAC_SUCCESS ;
}
int cac_LsaEnumSids ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct LsaEnumSids * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
uint32 num_sids ;
DOM_SID * sids ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_LSARPC ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op | | ! op - > in . pol ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
2006-03-11 02:17:00 +00:00
return CAC_FAILURE ;
2005-09-03 16:55:45 +00:00
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_LSARPC ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_lsa_enum_sids ( pipe_hnd , mem_ctx , op - > in . pol , & ( op - > out . resume_idx ) , op - > in . pref_max_sids , & num_sids , & sids ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) ) {
return CAC_FAILURE ;
}
op - > out . num_sids = num_sids ;
op - > out . sids = sids ;
return CAC_SUCCESS ;
}
int cac_LsaEnumAccountRights ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct LsaEnumAccountRights * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
uint32 count = 0 ;
char * * privs = NULL ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_LSARPC ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op - > in . pol ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
if ( ! op - > in . name & & ! op - > in . sid ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_LSARPC ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
if ( op - > in . name & & ! op - > in . sid ) {
DOM_SID * user_sid = NULL ;
uint32 * type ;
/*lookup the SID*/
2006-02-03 22:19:41 +00:00
hnd - > status = rpccli_lsa_lookup_names ( pipe_hnd , mem_ctx , op - > in . pol , 1 , ( const char * * ) & ( op - > in . name ) , NULL , & user_sid , & type ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
op - > in . sid = user_sid ;
}
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_lsa_enum_account_rights ( pipe_hnd , mem_ctx , op - > in . pol , op - > in . sid ,
2005-09-03 16:55:45 +00:00
& count , & privs ) ;
if ( ! NT_STATUS_IS_OK ( hnd - > status ) ) {
return CAC_FAILURE ;
}
op - > out . num_privs = count ;
op - > out . priv_names = privs ;
return CAC_SUCCESS ;
}
int cac_LsaEnumTrustedDomains ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct LsaEnumTrustedDomains * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd ;
2005-09-03 16:55:45 +00:00
uint32 num_domains ;
char * * domain_names ;
DOM_SID * domain_sids ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_LSARPC ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op - > in . pol ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_LSARPC ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_lsa_enum_trust_dom ( pipe_hnd , mem_ctx , op - > in . pol , & ( op - > out . resume_idx ) , & num_domains , & domain_names , & domain_sids ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) ) {
return CAC_FAILURE ;
}
op - > out . num_domains = num_domains ;
op - > out . domain_names = domain_names ;
op - > out . domain_sids = domain_sids ;
return CAC_SUCCESS ;
}
int cac_LsaOpenTrustedDomain ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct LsaOpenTrustedDomain * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
POLICY_HND * dom_pol = NULL ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_LSARPC ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op - > in . pol | | ! op - > in . access | | ! op - > in . domain_sid ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_LSARPC ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
dom_pol = talloc ( mem_ctx , POLICY_HND ) ;
if ( ! dom_pol ) {
hnd - > status = NT_STATUS_NO_MEMORY ;
errno = ENOMEM ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_lsa_open_trusted_domain ( pipe_hnd , mem_ctx , op - > in . pol , op - > in . domain_sid , op - > in . access , dom_pol ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) ) {
return CAC_FAILURE ;
}
op - > out . domain_pol = dom_pol ;
return CAC_SUCCESS ;
}
int cac_LsaQueryTrustedDomainInfo ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct LsaQueryTrustedDomainInfo * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
LSA_TRUSTED_DOMAIN_INFO * dom_info ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_LSARPC ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op - > in . pol | | ! op - > in . info_class ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
if ( ! op - > in . domain_sid & & ! op - > in . domain_name ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_LSARPC ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
if ( op - > in . domain_sid ) {
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_lsa_query_trusted_domain_info_by_sid ( pipe_hnd , mem_ctx , op - > in . pol , op - > in . info_class , op - > in . domain_sid , & dom_info ) ;
2005-09-03 16:55:45 +00:00
}
else if ( op - > in . domain_name ) {
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_lsa_query_trusted_domain_info_by_name ( pipe_hnd , mem_ctx , op - > in . pol , op - > in . info_class , op - > in . domain_name , & dom_info ) ;
2005-09-03 16:55:45 +00:00
}
if ( ! NT_STATUS_IS_OK ( hnd - > status ) ) {
return CAC_FAILURE ;
}
op - > out . info = dom_info ;
return CAC_SUCCESS ;
}
int cac_LsaEnumPrivileges ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct LsaEnumPrivileges * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
2005-10-18 03:24:00 +00:00
uint32 num_privs ;
2005-09-03 16:55:45 +00:00
char * * priv_names ;
uint32 * high_bits ;
uint32 * low_bits ;
if ( ! hnd ) {
return CAC_FAILURE ;
}
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_LSARPC ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op | | ! op - > in . pol ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_LSARPC ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_lsa_enum_privilege ( pipe_hnd , mem_ctx , op - > in . pol , & ( op - > out . resume_idx ) , op - > in . pref_max_privs ,
2005-09-03 16:55:45 +00:00
& num_privs , & priv_names , & high_bits , & low_bits ) ;
if ( ! NT_STATUS_IS_OK ( hnd - > status ) ) {
return CAC_FAILURE ;
}
op - > out . num_privs = num_privs ;
op - > out . priv_names = priv_names ;
op - > out . high_bits = high_bits ;
op - > out . low_bits = low_bits ;
return CAC_SUCCESS ;
}
int cac_LsaOpenAccount ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct LsaOpenAccount * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
POLICY_HND * user_pol = NULL ;
if ( ! hnd ) {
return CAC_FAILURE ;
}
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_LSARPC ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op | | ! op - > in . pol ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
if ( ! op - > in . sid & & ! op - > in . name ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
/*look up the user's SID if we have to*/
if ( op - > in . name & & ! op - > in . sid ) {
DOM_SID * user_sid = NULL ;
uint32 * type ;
/*lookup the SID*/
2006-02-03 22:19:41 +00:00
hnd - > status = rpccli_lsa_lookup_names ( pipe_hnd , mem_ctx , op - > in . pol , 1 , ( const char * * ) & ( op - > in . name ) , NULL , & user_sid , & type ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
op - > in . sid = user_sid ;
}
user_pol = talloc ( mem_ctx , POLICY_HND ) ;
if ( ! user_pol ) {
hnd - > status = NT_STATUS_NO_MEMORY ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_lsa_open_account ( pipe_hnd , mem_ctx , op - > in . pol , op - > in . sid , op - > in . access , user_pol ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) ) {
2006-02-20 17:59:58 +00:00
TALLOC_FREE ( user_pol ) ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
op - > out . user = user_pol ;
return CAC_SUCCESS ;
}
int cac_LsaAddPrivileges ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct LsaAddPrivileges * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
DOM_SID * user_sid = NULL ;
uint32 * type = NULL ;
if ( ! hnd ) {
return CAC_FAILURE ;
}
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_LSARPC ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op | | ! op - > in . pol | | ! op - > in . priv_names ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
if ( ! op - > in . sid & & ! op - > in . name ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_LSARPC ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
if ( op - > in . name & & ! op - > in . sid ) {
/*lookup the SID*/
2006-02-03 22:19:41 +00:00
hnd - > status = rpccli_lsa_lookup_names ( pipe_hnd , mem_ctx , op - > in . pol , 1 , ( const char * * ) & ( op - > in . name ) , NULL , & user_sid , & type ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
op - > in . sid = user_sid ;
}
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_lsa_add_account_rights ( pipe_hnd , mem_ctx , op - > in . pol , * ( op - > in . sid ) , op - > in . num_privs , ( const char * * ) op - > in . priv_names ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) ) {
return CAC_FAILURE ;
}
return CAC_SUCCESS ;
}
int cac_LsaRemovePrivileges ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct LsaRemovePrivileges * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
DOM_SID * user_sid = NULL ;
uint32 * type = NULL ;
if ( ! hnd ) {
return CAC_FAILURE ;
}
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_LSARPC ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op | | ! op - > in . pol | | ! op - > in . priv_names ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
if ( ! op - > in . sid & & ! op - > in . name ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_LSARPC ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
if ( op - > in . name & & ! op - > in . sid ) {
/*lookup the SID*/
2006-02-03 22:19:41 +00:00
hnd - > status = rpccli_lsa_lookup_names ( pipe_hnd , mem_ctx , op - > in . pol , 1 , ( const char * * ) & ( op - > in . name ) , NULL , & user_sid , & type ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
op - > in . sid = user_sid ;
}
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_lsa_remove_account_rights ( pipe_hnd , mem_ctx , op - > in . pol , * ( op - > in . sid ) , False , op - > in . num_privs , ( const char * * ) op - > in . priv_names ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) ) {
return CAC_FAILURE ;
}
return CAC_SUCCESS ;
}
int cac_LsaClearPrivileges ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct LsaClearPrivileges * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
DOM_SID * user_sid = NULL ;
uint32 * type = NULL ;
if ( ! hnd ) {
return CAC_FAILURE ;
}
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_LSARPC ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op | | ! op - > in . pol ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
if ( ! op - > in . sid & & ! op - > in . name ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_LSARPC ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
if ( op - > in . name & & ! op - > in . sid ) {
/*lookup the SID*/
2006-02-03 22:19:41 +00:00
hnd - > status = rpccli_lsa_lookup_names ( pipe_hnd , mem_ctx , op - > in . pol , 1 , ( const char * * ) & ( op - > in . name ) , NULL , & user_sid , & type ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
op - > in . sid = user_sid ;
}
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_lsa_remove_account_rights ( pipe_hnd , mem_ctx , op - > in . pol , * ( op - > in . sid ) , True , 0 , NULL ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) ) {
return CAC_FAILURE ;
}
return CAC_SUCCESS ;
}
int cac_LsaSetPrivileges ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct LsaAddPrivileges * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
DOM_SID * user_sid = NULL ;
uint32 * type = NULL ;
if ( ! hnd ) {
return CAC_FAILURE ;
}
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_LSARPC ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op | | ! op - > in . pol | | ! op - > in . priv_names ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
if ( ! op - > in . sid & & ! op - > in . name ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_LSARPC ) ;
if ( ! pipe_hnd ) {
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
if ( op - > in . name & & ! op - > in . sid ) {
/*lookup the SID*/
2006-02-03 22:19:41 +00:00
hnd - > status = rpccli_lsa_lookup_names ( pipe_hnd , mem_ctx , op - > in . pol , 1 , ( const char * * ) & ( op - > in . name ) , NULL , & user_sid , & type ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
op - > in . sid = user_sid ;
}
/*first remove all privileges*/
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_lsa_remove_account_rights ( pipe_hnd , mem_ctx , op - > in . pol , * ( op - > in . sid ) , True , 0 , NULL ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) ) {
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_lsa_add_account_rights ( pipe_hnd , mem_ctx , op - > in . pol , * ( op - > in . sid ) , op - > in . num_privs , ( const char * * ) op - > in . priv_names ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) ) {
return CAC_FAILURE ;
}
return CAC_SUCCESS ;
}
int cac_LsaGetSecurityObject ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct LsaGetSecurityObject * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
/*this is taken from rpcclient/cmd_lsarpc.c*/
uint16 info_level = 4 ;
SEC_DESC_BUF * sec_out = NULL ;
if ( ! hnd ) {
return CAC_FAILURE ;
}
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_LSARPC ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op | | ! op - > in . pol ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_LSARPC ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_lsa_query_secobj ( pipe_hnd , mem_ctx , op - > in . pol , info_level , & sec_out ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
op - > out . sec = sec_out ;
return CAC_FAILURE ;
}